var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
console.log(this.name + " says " + sth);
}
}
person.hello("hello world");
以前学过java,看到JavaScript的的内容的时候翻了两页,直接就跳过了,今天开始学Ajax重构的时候,才发现原来JavaScript有这么多不同,比如今天踩的坑this关键字。
首先我们要清楚几个概念——变量和属性。
有些书说的其实是不正确的,变量和属性是两个概念,我们来引用一个例子
var a =5;
b = 4; // equal to windows.b = 4
alert(delete a); // false
alert(delete b); // true
第一个a我们用var声明了,就是变量,而第二个没有就是属性而且是个全局属性,在浏览器意思就是为windows添加一个属性b,为它赋值4,接下来继续看alert的弹窗,第一个弹出false,第二个弹出true,因为
变量是无法被删除的,而属性可以。
继续。
this关键字在global code中的指的是全局对象,在浏览器就是指windows对象
alert(this)
//window
this单纯在函数中使用
function fooCoder(x) {
this.x = x;
}
fooCoder(2);
alert(x);// 全局变量x值为2
alert(delete x);//弹出true
在这里,this指的也是Windows对象,以上代码可以在chrome开发者工具(F12)的控制台直接运行,并且查看相关参数,我们可以看到这里也是弹出的全局属性x,且因为是属性所以可以被删除,弹出的窗口是true。
this作为对象方法调用
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
console.log(this.name + " says " + sth);
}
}
person.hello("hello world");
输出 foocoder says hello world。this指向person对象,即当前对象。这里有一个js对象的概念,如下
var person={firstname:"Bill", lastname:"Gates", id:5566};
其中person是对象,大括号里面的firstname是属性名,"Bill"是属性值。逗号分隔开每个属性,最后不能以分号结尾,具体请参阅w3school相关资料。之所以提出这个是为了不跟下面this在内部函数的用法混淆:
代码如下
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
var sayhello = function(sth) {
console.log(this.name + " says " + sth);
};
sayhello(sth);
}
}
person.hello("hello world");
//clever coder says hello world
这个代码块上面的那个代码块的最里面的function是作为一个叫hello的
方法,这个方法归属于person对象,所以方法里面的this指的是person对象。而现在这个内部函数你看清楚,hello方法里面又声明了一个叫sayhello的
函数,注意这里是等号,所以这就是容易混淆的地方。sayhello是一个函数块,并不是一个方法,而函数块默认里面的this是全局windows。
所以一般这个this如果你想绑定到person上就要用一个变量保存this先,例如取名that或者self
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
var that = this;
var sayhello = function(sth) {
console.log(that.name + " says " + sth);
};
sayhello(sth);
}
}
person.hello("hello world");
//foocoder says hello world
this作为构造函数时
new FooCoder();
函数内部的this指向新创建的对象。
apply 和 call 调用以及 bind 绑定:指向绑定的对象:
var myObject = {value: 100};
var foo = function(){
console.log(this);
};
foo(); // 全局变量 global
foo.apply(myObject); // { value: 100 }
foo.call(myObject); // { value: 100 }
var newFoo = foo.bind(myObject);
newFoo(); // { value: 100 }
apply() 方法接受两个参数第一个是函数运行的作用域,另外一个是一个参数数组(arguments)。
call() 方法第一个参数的意义与 apply() 方法相同,只是其他的参数需要一个个列举出来。
简单来说,call 的方式更接近我们平时调用函数,而 apply 需要我们传递 Array 形式的数组给它。它们是可以互相转换的。
现在来看一个题:
function test(){
a=5;
alert(a);
alert(this.a);
var a;
alert(this.a);
alert(a);
}
问:执行test()和new test() 返回值分别为啥?
答:返回结果,alert的内容:
test(): 5,10,10,5
new test():5,undefined,undefined,5
解释下:
在第一种情况 this指拥有test的对象,这儿是windows
第二种情况this指new创建的对象,因为未定义this.a,所以undefined
特别第二种情况,注意函数内部的a是没有var的,所以被定义成了一个全局变量