原型对象

一、原型

1562061884(1).jpg
function Person () {}
    var person = new Person()
    //构造函数 Person原型   Person.prototype
    Person.prototype.constructor === Person
    person.__proto__ === Person.prototype
    person.constructor === Person //此constructor即为原型中的constructor属性   原型中的所有属性实例都可以访问

相关方法:

1、isPrototypeOf()Object.getPrototypeOf()方法

    // isPrototypeOf() 方法

    Person.prototype.isPrototypeOf(person) // true

    // Object.getPrototypeOf() 方法
    Object.getPrototypeOf(person) === Person.prototype // true

    Person.prototype.name = 'Tom'

    Object.getPrototypeOf(person).name === 'Tom' // true

2、hasOwnProperty()方法,检测一个个属性是存在于实例中还是原型中。只有属性存在于实例中时,才会返回true。该方法是从Object继承来的。

    Person.prototype.name = 'Jack'

    var person1 = new Person();
    var person2 = new Person();
    person1.name = 'Tom'

    person1.hasOwnProperty('name')  // true
    person2.hasOwnProperty('name')  // false

    delete person1.name;
    person1.hasOwnProperty('name')  // false

注: Object.getOwnPropertyDescriptor()方法只能用于实例属性,要取得原型属性的描述符,必须直接在原型对象上调用Object.getOwnPropertyDescriptor()方法。

二、原型与in操作符

1、in

在对象中能够访问到给定属性(无论是存在于实例中还是原型中),使用in操作符返回true。

    Person.prototype.name = 'Jack'

    var person1 = new Person();
    var person2 = new Person();
    person1.name = 'Tom'

    'name' in person1 // true
    'name' in person2 // true

    delete person1.name;
     'name' in person1 // true

同时使用hasOwnProperty()in操作符,就可以确定该属性是存在于对象中还是原型中。

    function hasPropertyProperty (object, name) {
        return !object.hasOwnProperty(name) && (name in object);
    }

2、获取对象属性方法

1)for-in

for(var i in person1) {
    console.log(i) // name
}

2)Object.keys() 返回一个包含所有可枚举属性的字符串数组。返回一个数组
3)Object.getOwnPropertyNames() 得到所有实例属性,无论是否可枚举。包含了不可枚举的constructor属性
4)Object.values() 返回一个包含所有可枚举value的字符串数组。返回一个数组

三、重写原型对象

    function Person () {}
    Person.prototype = {
        constructor: Person,
        name: 'Tom',
        age: 27,
        job: 'software Engineer',
        sayName: function () {
            console.log(this.name);
        }
    }

注:1)重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;即在重写原型对象之前已经创建的实例引用的依然是最初的原型。
2)以这种方式重设constructor属性会导致它的[[Enumerable]]特性被设置为true,原生constructor属性是不可枚举的。可用Object.defineProperty更改。

Object.defineProperty(Person.protoytpe, 'constructor', {
        enumerable: false,
        value: Person
    })

3)原型对象中的属性值应避免为引用类型。否则某一实例对此属性值的修改会影响到其他实例。

    Person.prototype = {
        constructor: Person,
        name: 'Tom',
        age: 27,
        job: 'software Engineer',
        friends: ['Shelby', 'Court'],
        sayName: function () {
            console.log(this.name);
        }
    }

    var person1 = new Person();
    var person2 = new Person();
    person1.friends.push('Van');

    person1.friends // ["Shelby", "Court", "Van"]
    person2.friends // ["Shelby", "Court", "Van"]
    person1.friends === person2.friends // true

四、组合使用构造函数模式和原型模式创建对象

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。

function Person (name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.friends = ['Shelby', 'Court'];
    }
    
    Person.prototype = {
        constructor: Person,
        sayName: function () {
            alert(this.name);
        }
    }

你可能感兴趣的:(原型对象)