JavaScript 原型和原型链

  • JavaScript 中,每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。

  • 该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

  • 几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

构造函数实例

// 构造函数 Person()
function Person(name) {
    this.name = name; // 这里 name 是实例属性
}

Person.prototype.name = 'cedric'; // 这里 name 是原型属性
Person.prototype.age = '18';  // 这里 age 是原型属性


Object.prototype.address = 'shanghai';

// 创建一个Person的实例
var person1 = new Person('tom');
person1.name; // tom,  获取实例对象的属性时,如果在实例属性上存在,就直接读取,此时不管原型属性上是否还有相同的属性,这就是属性屏蔽

person1.age; // 18, 没有age的实例属性,所以就去实例的原型上找到age

person1.address; // shanghai, person1的原型Person上也没有找到 address, 所以就去Person的原型Object上面去找到address

person1.sex; // undefined, person1的原型Person上也没有找到 sex, 所以就去Person的原型Object上面去, 也没找到sex

person1.hasOwnProperty('name'); // true

原型链

JavaScript 中,每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

person1 ----> Person.prototype ----> Object.prototype ----> null
person1.__proto__ === Person.prototype;  // true, person1 的原型是:Person.prototype 对象
Person.prototype.__proto__ === Object.prototype;  // true, Person.prototype 的原型是: Object.prototype 对象

constructor

用 new Person() 创建的对象还从 Person 原型上获得了一个 constructor 属性,它指向函数 Person 本身

Person.prototype.constructor === Person; // true

person1.constructor  === Person; // true

person1.constructor === Person.prototype.constructor; // true

Object.getPrototypeOf()

Object.getPrototypeOf这个方法返回 proto 的值,可以获取到一个对象的原型

Object.getPrototypeOf(person1) === person1.__proto__; // true
Object.getPrototypeOf(person1) === Person.prototype; // true

hasOwnProperty

方法hasOwnProperty, 判断一个属性是否为实例属性属性

person1.hasOwnProperty('name'); // true
person1.hasOwnProperty('age'); // fasle

instanceof

instanceof 可以判断一个实例是否属于某构造函数

person1 instanceof Person;  // true

isPrototypeOf

isPrototypeOf()方法可以判断一个对象是否是另一个对象的原型

Person.prototype.isPrototypeOf(person1); // true

ES6 类

class Person {
    constructor(name) {
        this.name = name;
    }

    hello() {
        alert('Hello, ' + this.name + '!');
    }
}


// Student 需要name和grade两个参数,需要通过super(name)来调用父类的构造函数,否则父类的name属性无法正常初始化。
// Student 已经自动获得了父类 Student 的 hello 方法,我们又在子类中定义了新的 myGrade 方法。
class Student extends Person {
    constructor(name, grade) {
        super(name);
        this.grade = grade;
    }

    myGrade() {
        console.log('Grade is ', this.grade);
    }
} 

猜你喜欢

转载自www.cnblogs.com/cckui/p/11459791.html