Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

javascript对象

对象

JavaScript 语言使用构造函数(constructor)作为对象的模板。

构造函数的特点有两个。

  • 函数体内部使用了this关键字,代表了所要生成的对象实例。
  • 生成对象的时候,必须使用new命令。

new命令的作用,就是执行构造函数,返回一个实例对象。

new 命令的原理

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字。
  4. 开始执行构造函数内部的代码。

Object.create() 创建实例对象

现有的对象作为模板,生成新的实例对象,这时就可以使用Object.create()方法。

1
2
3
4
5
6
7
8
9
10
var person1 = {
name: '张三',
age: 38,
greeting: function() {
console.log('Hi! I\'m ' + this.name + '.');
}
};
var person2 = Object.create(person1);
person2.name // 张三
person2.greeting() // Hi! I'm 张三.

this关键字

this可以用在构造函数之中,表示实例对象。this都有一个共同点:它总是返回一个对象。

它的设计目的就是在函数体内部,指代函数当前的运行环境。

使用场合

全局环境使用this,它指的就是顶层对象window

构造函数中的this,指的是实例对象。

对象的方法里面包含thisthis的指向就是方法运行时所在的对象。

Function.prototype.call()

函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。

call方法的参数,应该是一个对象。如果参数为空、nullundefined,则默认传入全局对象。

继承

通过构造函数为实例对象定义属性,虽然很方便,但是有一个缺点。同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。

问题的解决方法,就是 JavaScript 的原型对象(prototype)。

原型对象的所有属性和方法,都能被实例对象共享。

每个函数都有一个prototype属性,指向一个对象。

1
2
function f() {}
typeof f.prototype // "object"

生成实例的时候,该属性会自动成为实例对象的原型。原型对象的属性不是实例对象自身的属性。

当实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。

原型对象的作用,就是定义所有实例对象共享的属性和方法。

对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding)。

原型对象相当于父类

constructor 属性

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。

constructor属性的作用是,可以得知某个实例对象,到底是哪一个构造函数产生的。

有了constructor属性,就可以从一个实例对象新建另一个实例。constructor属性表示原型对象与构造函数之间的关联关系。

instanceof 运算符

返回一个布尔值,表示对象是否为某个构造函数的实例。

instanceof运算符的左边是实例对象,右边是构造函数。它会检查右边构建函数的原型对象(prototype),是否在左边对象的原型链上。

构造函数的继承

第一步是在子类的构造函数中,调用父类的构造函数。

第二步,是让子类的原型指向父类的原型,这样子类就可以继承父类原型。

1
2
3
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;
Sub.prototype.method = '...';

Sub.prototype是子类的原型,要将它赋值为Object.create(Super.prototype),而不是直接等于Super.prototype。否则后面两行对Sub.prototype的操作,会连父类的原型Super.prototype一起修改掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Shape() {
this.x = 0;
this.y = 0;
}
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};

// 第一步,子类继承父类的实例
function Rectangle() {
Shape.call(this); // 调用父类构造函数
}
// 另一种写法
function Rectangle() {
this.base = Shape;
this.base();
}
// 第二步,子类继承父类的原型
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

评论