Javascript this 关键字 详解
作者:bea
一、this指向构造函数实例化对象 在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例: 代码如下: function Benjamin(username, sex) { this.username = username; this.sex = sex; } var benjamin = new Benjamin("zuojj", "male"); //Outputs: Benjamin{sex: "male",username:
一、this指向构造函数实例化对象
在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例:
代码如下:
function Benjamin(username, sex) {
this.username = username;
this.sex = sex;
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: undefined
console.log(ben);
当构造函数当做普通函数被调用时,并没有返回值,同时this指向全局对象。那么我们如何来避免因为缺少new关键字,而产生的问题呢?
代码如下:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
return new Benjamin(username, sex);
}
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: Benjamin {username: "zhangsan", sex: "female"}
console.log(ben);
在上例中,我们首先检查this是否是Benjammin的实例,如果不是,使用new自动调用构造函数,并实例化,这意味着,我们不再需要担心,遗漏new关键字实例化构造函数。当然这样我们可能会养成一个坏的习惯,如果避免这种现象呢?我们可以抛出一个错误,像下面这样:
代码如下:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
// If not, throw error.
throw new Error("`Benjamin` invoked without `new`");
}
}
二、this指向调用该函数的对象
看下面的例子:
代码如下:
var x = 10;
var obj = {
x: 10,
output: function() {
//Outputs: true
console.log(this === obj);
return this.x;
},
innerobj: {
x: 30,
output: function() {
//Outputs: true
console.log(this === obj.innerobj);
return this.x;
}
}
};
//Outputs: 10
console.log(obj.output());
//Outputs: 30
console.log(obj.innerobj.output());
三、this指向全局对象
在上面讨论构造函数的时候我们也讨论到不适用new的时候,this会指向全局对象,下面我们来看看两种常见的容易犯错的实例:
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
(function() {
//Outputs: true
console.log(this === window);
//Outputs: Inner: 100
console.log("Inner:" + this.x);
})();
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
在使用闭包的时候,作用域发生变化,this指向window(浏览器中)。
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
var output = obj.output;
//Outputs: 10
console.log(obj.output());
//Outputs: 100
console.log(output());
var obj2 = {
x: 30,
output: obj.output
}
//Outputs: 30
console.log(obj2.output());
此时this始终指向函数调用时的对象。
四、this指向apply/call()方法指派的对象
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
var obj2 = {
x: 40,
output: obj.output
}
//Outputs: 40
console.log(obj.output.call(obj2));
//Outputs: 10
console.log(obj2.output.apply(obj));
五、callback函数內的this指向调用该callback的函数的this所指向的对象
代码如下:
//<input type="text" value="3" id="txt_username">
$("#username").on("click", function() {
console.log(this.value);
});
六、Function.prototype.bind中的this
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. 实例一:
代码如下:
function person() {
return this.name;
}
//Function.prototype.bind
var per = person.bind({
name: "zuojj"
});
console.log(per);
var obj = {
name: "Ben",
person: person,
per: per
};
//Outputs: Ben, zuojj
console.log(obj.person(), obj.per());
实例二:
代码如下:
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
//Outputs: 81
console.log(module.getX());
var getX = module.getX;
//Outputs: 9, because in this case, "this" refers to the global object
console.log(getX);
// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
//Outputs: 81
console.log(boundGetX());
有用 | 无用
在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例:
代码如下:
function Benjamin(username, sex) {
this.username = username;
this.sex = sex;
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: undefined
console.log(ben);
当构造函数当做普通函数被调用时,并没有返回值,同时this指向全局对象。那么我们如何来避免因为缺少new关键字,而产生的问题呢?
代码如下:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
return new Benjamin(username, sex);
}
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: Benjamin {username: "zhangsan", sex: "female"}
console.log(ben);
在上例中,我们首先检查this是否是Benjammin的实例,如果不是,使用new自动调用构造函数,并实例化,这意味着,我们不再需要担心,遗漏new关键字实例化构造函数。当然这样我们可能会养成一个坏的习惯,如果避免这种现象呢?我们可以抛出一个错误,像下面这样:
代码如下:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
// If not, throw error.
throw new Error("`Benjamin` invoked without `new`");
}
}
二、this指向调用该函数的对象
看下面的例子:
代码如下:
var x = 10;
var obj = {
x: 10,
output: function() {
//Outputs: true
console.log(this === obj);
return this.x;
},
innerobj: {
x: 30,
output: function() {
//Outputs: true
console.log(this === obj.innerobj);
return this.x;
}
}
};
//Outputs: 10
console.log(obj.output());
//Outputs: 30
console.log(obj.innerobj.output());
三、this指向全局对象
在上面讨论构造函数的时候我们也讨论到不适用new的时候,this会指向全局对象,下面我们来看看两种常见的容易犯错的实例:
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
(function() {
//Outputs: true
console.log(this === window);
//Outputs: Inner: 100
console.log("Inner:" + this.x);
})();
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
在使用闭包的时候,作用域发生变化,this指向window(浏览器中)。
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
var output = obj.output;
//Outputs: 10
console.log(obj.output());
//Outputs: 100
console.log(output());
var obj2 = {
x: 30,
output: obj.output
}
//Outputs: 30
console.log(obj2.output());
此时this始终指向函数调用时的对象。
四、this指向apply/call()方法指派的对象
代码如下:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
var obj2 = {
x: 40,
output: obj.output
}
//Outputs: 40
console.log(obj.output.call(obj2));
//Outputs: 10
console.log(obj2.output.apply(obj));
五、callback函数內的this指向调用该callback的函数的this所指向的对象
代码如下:
//<input type="text" value="3" id="txt_username">
$("#username").on("click", function() {
console.log(this.value);
});
六、Function.prototype.bind中的this
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. 实例一:
代码如下:
function person() {
return this.name;
}
//Function.prototype.bind
var per = person.bind({
name: "zuojj"
});
console.log(per);
var obj = {
name: "Ben",
person: person,
per: per
};
//Outputs: Ben, zuojj
console.log(obj.person(), obj.per());
实例二:
代码如下:
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
//Outputs: 81
console.log(module.getX());
var getX = module.getX;
//Outputs: 9, because in this case, "this" refers to the global object
console.log(getX);
// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
//Outputs: 81
console.log(boundGetX());
有用 | 无用
猜你喜欢
您可能感兴趣的文章:
- Nodejs极简入门教程(二):定时器
- Nodejs极简入门教程(一):模块机制
- JavaScript极简入门教程(三):数组
- JavaScript极简入门教程(二):对象和函数
- JavaScript极简入门教程(一):基础篇
- 上传图片预览JS脚本 Input file图片预览的实现示例
- 实用框架(iframe)操作代码
- form.submit()不能提交表单的原因分析
- Google Maps API地图应用示例分享
- 深入分析JQuery和JavaScript的异同
- jquery实现导航固定顶部的效果仿蘑菇街
- 用jquery模仿的a的title属性的例子
- 运用jQuery定时器的原理实现banner图片切换
- 用简洁的jQuery方法toggleClass实现隔行换色
- jQuery实现的导航条切换可显示隐藏
- 原生js和jQuery随意改变div属性style的名称和值
- 一个不错的js html页面倒计时可精确到秒
- js实现select跳转功能代码
- Javascript原型链和原型的一个误区