前言 本篇文章将讲到之前new原理中的为讲到的call()方法
为什么要有this ?
- this 提供了一种更优雅的方式来隐式的传递一个对象的引用,可以让代码更加简洁利于复用
js
//需要给speek和identify显示传入一个上下文对象
function identfy(context) {
return context.name.toUpperCase(); //英文大写
}
function speak(context) {
var greeting = "hello ,I'm " + identfy(context) + ",I hate Trump!";
console.log(greeting);
}
var me = {
name: "",
};
speak(me);
function identfy1() {
return this.name.toUpperCase(); // toUpperCase(); //英文大写
}
function speak1() {
var greeting = "hello ,I'm " + identfy1.call(this) + ",I love China!";
console.log(greeting);
}
var me1 = {
name: "Donald Trump",
};
speak1.call(me1); //调用的时候

this可以使用在哪里?
- 函数作用域:
- 全局作用域:默认this指向的是window

- 块级作用域?不不没有它,只有上面两个,为什么?
js
//块级
{
let a = this;
console.log(a);
}
来,你看这段代码,块级作用域是指let的变量和{}一起是块级,那么这this就不是在块级里面了,实则是在全局window上哦
- this是一个代词,它代指一个对象
this的绑定规则
1.默认绑定---当函数 被独立调用时 ,函数的this默认指向到window
(即使this是在函数体里的,但是被独立调用,仍然会指向全局的window)
js
// 代指:
var a = 1; //挂在window
function foo() {
console.log(this.a);//this是在foo里面的,但它指向的是window
}
function Bar() {
var a = 2;
foo();//独立调用
}
Bar();
要在浏览器上才能看到挂在windowd的上的a,编译器上运行node结果是undefined,所以后续要用到window全局的,代码都在浏览器上执行
独立调用是什么?没有其他前缀的调用
js
var obj = { a: 1 ,
foo: function () {
console.log(this);
}//不是独立调用
};
obj.foo();
这段代码就不是独立调用 有obj去调用它
在来看下面这段代码: 同理因为是独立调用触发的是默认绑定,绑定在window,全局上,所以this是函数作用域外面的全局作用域
2.隐式绑定---当函数引用有上下文对象且被该对象调用时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
什么是函数引用 是指foo()不带() 的 foo
js
var a = 1;
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: function () {
console.log(this.a);
},
};
obj.foo();
var obj = {
a: 2,
foo: foo, //foo引用 来找找到函数
};
obj.foo();
var obj = {
a: 2,
foo: foo(),
};
obj.foo(); //报错
obj.foo
第一个obj与第二个obj是等同的,单写foo是指引用,v8执行时会去找foo变量或者函数,这里没有变量就会找到函数foo
第三种写法是错误的,foo()加了括号这里就是调用函数,而这里的函数没有返回值,这里的值就是undefin,那么foo:undefined
,而后在对象外面调用的话,obj.foo(),是调用名为foo的函数,但这里foo:undefined
值是undefined不是函数体,所以会报错,如果是obj.foo的话是指对象的一个属性,属性名为foo,并且这里没有做任何操作,也不会报错。
3.隐式丢失---当一个函数被多层对象调用时,函数的this会指向最近的那一层对象
js
var a = 1;
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo, //foo引用
};
var obj2 = {
a: 3,
obj:obj
};
obj2.obj.foo();
函数的this会指向最近的那一层对象即obj而不是obj2
4.显示绑定
1.fn.call(obj,x,y,....)显示的将fn里面的this绑定到obj对象上,并且call帮fn接收参数
js
function foo(x,y){
console.log(this.a,x+y);
}
var obj={
a:2
}
foo.call(obj,1,2)//显示绑定
foo.call(1,1,2)//如果第一个参数不是对象,默认给一个null
foo.call(null,1,2)//显示绑定
call方法是定义在Funtion.prototype上的foo.prototype.__proto__===Function.prototype
call将this指向obj ,并且帮忙接收foo参数和调用foo函数
2.fn.apply(obj,[x,y,....])显示的将fn里面的this绑定到obj对象上,并且apply帮fn接收参数,参数必须以数 组的形式盛放
js
foo.apply(obj,[1,2])//区别
3.fn.bind(obj,x,y,....)(x,x, ....)显示的将fn里面的this绑定到obj对象上,并且bind会返回一个新的函数,bind和新函数都可以负责帮fn接收参数,参数零散的传入
js
const bar=foo.bind(obj,1,2)//
bar()
const bar1=foo.bind(obj)
bar1(1,2)
const bar3=foo.bind(obj,2,4)
bar3(1)
bind会返回一个新的函数体,但是我们要自己触发这个函数,才能接着触发foo的函数
5.new绑定 --new 的原理会导致函数的this绑定到实例对象上
js
function Person() {
//var obj = {};
//Person.call(obj);
this.name = "特朗普";
this.age = 18;
console.log(this);
//obj.__proto__ = Person.prototype;
//return obj;
}
const p1 = new Person();
因为new的过程使用了call()方法将将Person的this指向obj,最后将obj返回给实例对象,即即把Person的this绑定到了实例对象上
箭头函数
箭头函数中没有this这个概念,写在了箭头函数的中的this,也是它外层那个非箭头函数的this
js
function a() {
console.log(this);
let b = function () {
let c = () => {
let d = () => {
console.log(this);//箭头函数里面没有this这个关键字
};
d();
};
c();
};
b();
}
a();
这的this是在fuction a(){} 里面的,但不指向funtion a(){},因为默认绑定规则,所以是指向window的
js
var a = 1
var obj = {
a: 2,
bar: function() {
const baz = () => {
console.log(this.a);
}
baz()
}
}
obj.bar()

如有错误欢迎指正,欢迎各位友友评论点赞!