构造函数
var Vehicle = function() {
this.price = 1000;
}
构造函数的特点有两个:
- 函数体内部使用了this关键字,代表了所要生成的对象实例。
- 生成对象的时候,必须使用new命令。
new 命令
1. 基本用法
new命令的作用,就是执行构造函数,返回一个实例对象。
var Vehicle = function () {
this.price = 1000;
};
var v = new Vehicle();
v.price // 1000
var Vehicle = function (){
this.price = 1000;
};
var v = Vehicle();
v // undefined
price // 1000
上面代码中,调用Vehicle构造函数时,忘了加上new命令。结果,变量v变成了undefined,而price属性变成了全局变量。因此,应该非常小心,避免不使用new命令、直接调用构造函数。
为了保证构造函数必须与new命令一起使用,一个解决办法是,构造函数内部使用严格模式,即第一行加上use strict。这样的话,一旦忘了使用new命令,直接调用构造函数就会报错。
2. new 命令的原理
使用new命令时,它后面的函数依次执行下面的步骤。
- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的prototype属性。
- 将这个空对象赋值给函数内部的this关键字。
- 开始执行构造函数内部的代码。
3. Object.create() 创建实例对象
构造函数作为模板,可以生成实例对象。但是,有时拿不到构造函数,只能拿到一个现有的对象。我们希望以这个现有的对象作为模板,生成新的实例对象,这时就可以使用Object.create()方法。
This
实质
js 之所以有this的设计,跟内存里面的数据结构有关系
var obj = {foo: 5};
将一个对象赋值给obj。 Javascript会先在内存里,生成一个对象 {foo: 5},然后把这个对象的内存地址赋值给obj,也就是说obj是一个reference。后面要是要取obj.foo, 要先从obj中拿到内存地址,然后再从该地址读出原始的对象
var obj = { foo: function () {} };
这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性
{
foo: {
[[value]]: 函数的地址
...
}
}
var f = function () {
console.log(this.x);
}
var x = 1;
var obj = {
f: f,
x: 2,
};
// 单独执行
f() // 1
// obj 环境执行
obj.f() // 2
如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。
var a = {
b: {
m: function() {
console.log(this.p);
},
p: 'Hello'
}
};
var hello = a.b.m;
hello() // undefined
var hello = a.b;
hello.m() // Hello
使用场合
1. 全局环境
全局环境使用this,它指的就是顶层对象window
this === window //true
function() {
console.log(this === window);
}
2. 构造函数
构造函数中的this,指的是实例对象
var Obj = function (p) {
this.p = p;
};
``
这样的结构是很清晰的,问题在于属性的值可能是一个函数
3. 对象的方法
如果对象的方法里面包含this,this的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。
var obj = {
foo: function() {
console.log(this);
}
}
obj.foo(); //obj
但是下面的这几种方法,都会改变this的指向
(obj.foo = obj.foo)() //window
上面代码中,obj.foo就是一个值。这个值真正调用的时候,运行环境已经不是obj了,而是全局环境,所以this不再指向obj
网友评论