this指向及改变this指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。
至于为什么这么说,举一个栗子:
function Person(){
this.name = arguments[0];
this.age = arguments[1];
this.sex = arguments[2];
this.sayhi = function(){
console.log('你好啊,'+this.name);
}
};
var person1 = new Person('lili',19,'woman');
console.log(person1.sayhi());//你好啊,lili
上述的栗子用的是构造函数实例化的对象,this指向的是实例化对象,谁调用this指向谁,函数Person中的this并没有一开始就指向它自身,只有执行了才知道this该指向谁。
对于普通函数而言,this指向的是window(浏览器环境下),在node中指向global。
// 浏览器环境下
console.dir(this);//window
// node下
console.log(this);//Object [global]
针对对象中的函数,它永远指向真正的调用者
let obj1={
a:111
}
let obj2={
a:222,
fn:function(){
console.log(this.a);
}
}
obj1.fn=obj2.fn;
obj1.fn(); //111
new关键字的实例化对象中,指向实例的对象
严格模式下的this指向:
严格模式下指向不同点在于,严格模式的全局作用域下的函数指向不再是window而是undefined。
bind();
在不使用bind改变this指向空间时,两个均为John,但由于bind的特殊作用,将其指向绑定为window的,因为最后一个输出了全局变量的nam,这个方法适用于稍后执行,因为该方法不会立马执行,它返回一个改变了this指向的函数。参数是放在bind()第二个之后的位置,多个参数按序写入。
var name = 'sally';
function sayName(){
return this.name;
}
function sayName2(){
return this.name
}
var o = {
'name':'John',
sayName:sayName,
sayName2:sayName2.bind(window)
};
console.log(o.sayName()); //John
console.log(o.sayName2());//sally
apply()
call和apply:
相同点:call和apply均可以改变this指向,都是立即执行该函数。
不同点:call接受的参数为一个一个的,但是apply接受的参数只能为一个严格的数组(详情见如下的代码演示)
apply的第一个参数为this要执行的对象,该对象是谁并无限制,bind、call都是这样。
var name = 'sally';
function sayName(){
console.log(this.name);
}
var o = {
'name':'John',
sayName:sayName
};
sayName.apply(o);//Jhon
call()
使用 call() 方法,您可以编写能够在不同对象上使用的方法。
函数是对象方法在 JavaScript 中,函数是对象的方法。
如果一个函数不是 JavaScript 对象的方法,那么它就是全局对象的函数。
下面的例子创建了带有三个属性的对象(firstName、lastName、fullName)。
var person = {
firstName:"Bill",
lastName: "Gates",
fullName: function () {
console.log (this.firstName + this.lastName);
}
}
var person1 = {
firstName:"尼古拉斯",
lastName: "赵四",
}
person.fullName.call(person1); // 尼古拉斯赵四