一、this指向构造函数实例化对象6uUHTML5中文学习网 - HTML5先行者学习网
在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
function Benjamin(username, sex) {6uUHTML5中文学习网 - HTML5先行者学习网
this.username = username;6uUHTML5中文学习网 - HTML5先行者学习网
this.sex = sex;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
var benjamin = new Benjamin("zuojj", "male");6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: Benjamin{sex: "male",username: "zuojj"}6uUHTML5中文学习网 - HTML5先行者学习网
console.log(benjamin);6uUHTML5中文学习网 - HTML5先行者学习网
var ben = Benjamin("zhangsan", "female");6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: undefined6uUHTML5中文学习网 - HTML5先行者学习网
console.log(ben);6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网当构造函数当做普通函数被调用时,并没有返回值,同时this指向全局对象。那么我们如何来避免因为缺少new关键字,而产生的问题呢?6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
function Benjamin(username, sex) {6uUHTML5中文学习网 - HTML5先行者学习网
//Check whether "this" is a "Benjamin" object6uUHTML5中文学习网 - HTML5先行者学习网
if(this instanceof Benjamin) {6uUHTML5中文学习网 - HTML5先行者学习网
this.username = username;6uUHTML5中文学习网 - HTML5先行者学习网
this.sex = sex;6uUHTML5中文学习网 - HTML5先行者学习网
}else {6uUHTML5中文学习网 - HTML5先行者学习网
return new Benjamin(username, sex);6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
var benjamin = new Benjamin("zuojj", "male");6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: Benjamin{sex: "male",username: "zuojj"}6uUHTML5中文学习网 - HTML5先行者学习网
console.log(benjamin);6uUHTML5中文学习网 - HTML5先行者学习网
var ben = Benjamin("zhangsan", "female");6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: Benjamin {username: "zhangsan", sex: "female"} 6uUHTML5中文学习网 - HTML5先行者学习网
console.log(ben);6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网在上例中,我们首先检查this是否是Benjammin的实例,如果不是,使用new自动调用构造函数,并实例化,这意味着,我们不再需要担心,遗漏new关键字实例化构造函数。当然这样我们可能会养成一个坏的习惯,如果避免这种现象呢?我们可以抛出一个错误,像下面这样:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
function Benjamin(username, sex) {6uUHTML5中文学习网 - HTML5先行者学习网
//Check whether "this" is a "Benjamin" object6uUHTML5中文学习网 - HTML5先行者学习网
if(this instanceof Benjamin) {6uUHTML5中文学习网 - HTML5先行者学习网
this.username = username;6uUHTML5中文学习网 - HTML5先行者学习网
this.sex = sex;6uUHTML5中文学习网 - HTML5先行者学习网
}else {6uUHTML5中文学习网 - HTML5先行者学习网
// If not, throw error.6uUHTML5中文学习网 - HTML5先行者学习网
throw new Error("`Benjamin` invoked without `new`");6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网二、this指向调用该函数的对象6uUHTML5中文学习网 - HTML5先行者学习网
看下面的例子:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
var x = 10;6uUHTML5中文学习网 - HTML5先行者学习网
var obj = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 10,6uUHTML5中文学习网 - HTML5先行者学习网
output: function() {6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: true6uUHTML5中文学习网 - HTML5先行者学习网
console.log(this === obj);6uUHTML5中文学习网 - HTML5先行者学习网
return this.x;6uUHTML5中文学习网 - HTML5先行者学习网
},6uUHTML5中文学习网 - HTML5先行者学习网
innerobj: {6uUHTML5中文学习网 - HTML5先行者学习网
x: 30,6uUHTML5中文学习网 - HTML5先行者学习网
output: function() {6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: true6uUHTML5中文学习网 - HTML5先行者学习网
console.log(this === obj.innerobj);6uUHTML5中文学习网 - HTML5先行者学习网
return this.x;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 106uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.output());6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 306uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.innerobj.output());6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网三、this指向全局对象6uUHTML5中文学习网 - HTML5先行者学习网
在上面讨论构造函数的时候我们也讨论到不适用new的时候,this会指向全局对象,下面我们来看看两种常见的容易犯错的实例:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
var x = 100;6uUHTML5中文学习网 - HTML5先行者学习网
var obj = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 10,6uUHTML5中文学习网 - HTML5先行者学习网
output: function() {6uUHTML5中文学习网 - HTML5先行者学习网
(function() {6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: true6uUHTML5中文学习网 - HTML5先行者学习网
console.log(this === window);6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: Inner: 1006uUHTML5中文学习网 - HTML5先行者学习网
console.log("Inner:" + this.x);6uUHTML5中文学习网 - HTML5先行者学习网
})();6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
return this.x;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 106uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.output());6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网在使用闭包的时候,作用域发生变化,this指向window(浏览器中)。6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
var x = 100;6uUHTML5中文学习网 - HTML5先行者学习网
var obj = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 10,6uUHTML5中文学习网 - HTML5先行者学习网
output: function() {6uUHTML5中文学习网 - HTML5先行者学习网
return this.x;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
var output = obj.output;6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 106uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.output());6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 1006uUHTML5中文学习网 - HTML5先行者学习网
console.log(output());6uUHTML5中文学习网 - HTML5先行者学习网
var obj2 = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 30,6uUHTML5中文学习网 - HTML5先行者学习网
output: obj.output6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 306uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj2.output());6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网此时this始终指向函数调用时的对象。6uUHTML5中文学习网 - HTML5先行者学习网
四、this指向apply/call()方法指派的对象6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
var x = 100;6uUHTML5中文学习网 - HTML5先行者学习网
var obj = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 10,6uUHTML5中文学习网 - HTML5先行者学习网
output: function() {6uUHTML5中文学习网 - HTML5先行者学习网
return this.x;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 106uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.output());6uUHTML5中文学习网 - HTML5先行者学习网
var obj2 = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 40,6uUHTML5中文学习网 - HTML5先行者学习网
output: obj.output6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 406uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.output.call(obj2));6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 106uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj2.output.apply(obj));6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网五、callback函数 的this指向调用该callback的函数的this所指向的对象6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
//<input type="text" value="3" id="txt_username">6uUHTML5中文学习网 - HTML5先行者学习网
$("#username").on("click", function() {6uUHTML5中文学习网 - HTML5先行者学习网
console.log(this.value);6uUHTML5中文学习网 - HTML5先行者学习网
});6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网六、Function.prototype.bind中的this6uUHTML5中文学习网 - HTML5先行者学习网
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.6uUHTML5中文学习网 - HTML5先行者学习网
实例一:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
function person() {6uUHTML5中文学习网 - HTML5先行者学习网
return this.name;6uUHTML5中文学习网 - HTML5先行者学习网
}6uUHTML5中文学习网 - HTML5先行者学习网
//Function.prototype.bind6uUHTML5中文学习网 - HTML5先行者学习网
var per = person.bind({6uUHTML5中文学习网 - HTML5先行者学习网
name: "zuojj"6uUHTML5中文学习网 - HTML5先行者学习网
});6uUHTML5中文学习网 - HTML5先行者学习网
console.log(per);6uUHTML5中文学习网 - HTML5先行者学习网
var obj = {6uUHTML5中文学习网 - HTML5先行者学习网
name: "Ben",6uUHTML5中文学习网 - HTML5先行者学习网
person: person,6uUHTML5中文学习网 - HTML5先行者学习网
per: per6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: Ben, zuojj6uUHTML5中文学习网 - HTML5先行者学习网
console.log(obj.person(), obj.per());6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网实例二:6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网
this.x = 9; 6uUHTML5中文学习网 - HTML5先行者学习网
var module = {6uUHTML5中文学习网 - HTML5先行者学习网
x: 81,6uUHTML5中文学习网 - HTML5先行者学习网
getX: function() { return this.x; }6uUHTML5中文学习网 - HTML5先行者学习网
};6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 816uUHTML5中文学习网 - HTML5先行者学习网
console.log(module.getX()); 6uUHTML5中文学习网 - HTML5先行者学习网
var getX = module.getX;6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 9, because in this case, "this" refers to the global object6uUHTML5中文学习网 - HTML5先行者学习网
console.log(getX); 6uUHTML5中文学习网 - HTML5先行者学习网
// create a new function with 'this' bound to module6uUHTML5中文学习网 - HTML5先行者学习网
var boundGetX = getX.bind(module);6uUHTML5中文学习网 - HTML5先行者学习网
//Outputs: 816uUHTML5中文学习网 - HTML5先行者学习网
console.log(boundGetX());6uUHTML5中文学习网 - HTML5先行者学习网
6uUHTML5中文学习网 - HTML5先行者学习网