js中的this

参考博客
js中的this,表示函数的当前执行上下文,js中函数调用主要有以下几种方式,
函数调用 alert(‘hello world’);
方法调用 console.log(‘hello world’);
构造函数 new RegExp(‘\d’)
隐式调用 alert.call(undefined,’hello world’)
理解this的关键是要清楚知道函数的调用以及如何影响上下文
函数表达式 表示定义函数并且在其中使用

1
2
3
4
function hello(name){
return 'hello' + name;
}
hello("ckq");

1.在函数调用中的this
this在函数调用中是一个全局对象
对象是由执行环境来决定的,在浏览器中,this是window对象
严格模式下的this
this在严格模式的函数调用中为undefined
严格模式是在ecs5中引入的,提供了更好的安全性和更强的类型检查。
2.方法调用
当一个表达式以属性访问的形式来执行时,执行的是方法调用,
例如myObject.helloFunction(),[1,2].join(‘,’);
在方法调用中,this是拥有这个方法的对象
object.create也是创建一个对象,调用的上下文仍然是对象本身
在es6的语法中,方法调用的上下文也是实例本身

陷阱:将方法与其对象分离
方法可以从对象中提取到一个单独的变量中,
const alone = myObj.method;
当方法调用的时候,与原始对象alone分离,如果方法在没有对象的情况下调用,那么函数调用就会发生,此时this指向全局对象window,严格模式下是undefined.
3.构造函数调用,

1
2
3
4
5
6
7
8
function country(name,travel){
this.name = name;
this.travel = travel;
}
country.travel = function() {
this.travel = true;
}
const frace = new country('france';false);

new City(‘paris’,false);是构造函数的调用,这个对象的初始化由这个类中一个特殊的方法constructor来处理,this指向新创建的对象
构造函数创建了一个新的空的对象,它从构造函数的原型继承了属性。构造函数的作用就是去初始化这个对象。 可能你已经知道了,在这种类型的调用中,上下文指向新创建的实例。
myobject.fun()时会执行构造函数的调用而不是方法调用
在构造函数调用中this指向新创建的对象
当忘记new的时候,在函数调用中,this是window对象,因此 Vehicle(’Car’,4)在window对象上设置属性。 显然这是错误,它并没有创建新对象
5 隐式调用
使用myFun.call()或者myFun.apply()方法调用函数的时候,执行的是隐式调用
对象的类型是function,.call()和.apply调用具有可配置的上下文的函数

方法 .call(thisArg[, arg1[, arg2[, …]]])将接受的第一个参数thisArg作为调用时的上下文,arg1, arg2, …这些则作为参数传入被调用的函数。
方法.apply(thisArg, [args])将接受的第一个参数thisArg作为调用时的上下文,并且接受另一个类似数组的对象[arg1, arg2, …]作为被调用函数的参数传入。

1
2
3
4
5
function increment(number){
return ++number;
}
increment.call(undefined,10); //11
increment.apply(undefined,[10]); //11

隐式调用非常有用。例如为了解决方法调用时,this总是window或严格模式下的undefined的上下文问题。隐式调用可以模拟在一个对象上调用另外某个方法

1
2
3
4
5
    function Runner(str) {
return str + this.name;
}
var rabbit = {name:'white '};
console.log(Runner.call(rabbit,"ccc"));

.bind()创建一个永久的上下文连接,并且始终保持它,一个函数不能通过.call或者.apply来改变它的上下文,甚至是再次绑定也没什么作用
6.箭头函数
箭头函数用以更短的形式声明函数,并在词法上绑定上下文,

1
2
3
4
const hello = (name) => {
return 'hello' + name;
}
hello('world');

箭头函数是匿名的,这意味着name属性是一个空字符串’’;跟常规函数也相反,也不提供arguments对象。但是,在es6中通过剩余参数修复了。

1
2
3
4
5
const sumArguments = (...args) => {
return args.reduce((result,item) => {
result + item;
})
}

**注意,箭头函数不会创建自己的上下文,而是从定义他的外部来获取上下文,换句话说,箭头函数在词汇上获取上下文。

1
2
3
4
5
this;
var myFunc = () => {
this;
}
myFunc();