js原型

2019-11-22 hubo JavaScript

原型和继承:


原型(Prototype)是 JavaScript 中最容易搞混的概念,其中一个原因是prototype可以用在两个不同的情形下。

  • 原型关系
    每一个对象都有一个prototype对象,里面包含了所有它的原型的属性。
    .__proto__
    是一个不正规的机制(ES6 中提供),用来获取一个对象的 prototype。你可以理解为它指向对象的parent
    所有普通的对象都继承.constructor属性,它指向该对象的构造函数。当一个对象通过构造函数实现的时候,__proto__属性指向构造函数的构造函数的.prototypeObject.getPrototypeOf()是 ES5 的标准函数,用来获取一个对象的原型。
  • 原型属性
    每一个函数都有一个.prototype属性,它包含了所有可以被继承的属性。该对象默认包含了指向原构造函数的.constructor属性。每一个使用构造函数创建的对象都有一个构造函数属性。

接下来通过例子来帮助理解:

function Dog(breed, name) {

    (this.breed = breed), (this.name = name);

}

Dog.prototype.describe = function() {

    console.log(`${this.name} is a ${this.breed}`);

};

const rusty = new Dog("Beagle", "Rusty");


/* .prototype 属性包含了构造函数以及构造函数中在prototype上定义的属性。*/

console.log(Dog.prototype); // { describe: ƒ , constructor: ƒ }


/* 使用Dog构造函数构造的对象 */

console.log(rusty); //  { breed: "Beagle", name: "Rusty" }

/* 从构造函数的原型中继承下来的属性或函数 */

console.log(rusty.describe()); // "Rusty is a Beagle"

/* .__proto__ 属性指向构造函数的.prototype属性 */

console.log(rusty.__proto__); // { describe: ƒ , constructor: ƒ }

/* .constructor 属性指向构造函数 */

console.log(rusty.constructor); // ƒ Dog(breed, name) { ... }

JavaScript 的使用可以说相当灵活,为了避免出 bug 了不知道,不妨接入Fundebug线上实时监控。


原型链:


原型链是指对象之间通过 prototype 链接起来,形成一个有向的链条。当访问一个对象的某个属性的时候,JavaScript 引擎会首先查看该对象是否包含该属性。如果没有,就去查找对象的 prototype 中是否包含。以此类推,直到找到该属性或则找到最后一个对象。最后一个对象的 prototype 默认为 null

拥有 vs 继承

一个对象有两种属性,分别是它自身定义的和继承的。

function Car() {}

Car.prototype.wheels = 4;

Car.prototype.airbags = 1;


var myCar = new Car();

myCar.color = "black";


/*  原型链中的属性也可以通过in来查看:  */

console.log("airbags" in myCar); // true

console.log(myCar.wheels); // 4

console.log(myCar.year); // undefined


/*  通过hasOwnProperty来查看是否拥有该属性:  */

console.log(myCar.hasOwnProperty("airbags")); // false — Inherited

console.log(myCar.hasOwnProperty("color")); // true


Object.create(obj) 创建一个新的对象,prototype 指向obj

var dog = { legs: 4 };

var myDog = Object.create(dog);


console.log(myDog.hasOwnProperty("legs")); // false

console.log(myDog.legs); // 4

console.log(myDog.__proto__ === dog); // true



继承是引用传值:


继承属性都是通过引用的形式。我们通过例子来形象理解:

var objProt = { text: "original" };

var objAttachedToProt = Object.create(objProt);

console.log(objAttachedToProt.text); // original


// 我们更改objProttext属性,objAttachedToProttext属性同样更改了

objProt.text = "prototype property changed";

console.log(objAttachedToProt.text); // prototype property changed


// 但是如果我们讲一个新的对象赋值给objProt,那么objAttachedToProttext属性不受影响

objProt = { text: "replacing property" };

console.log(objAttachedToProt.text); // prototype property changed

网站备案号:京ICP备11043289号-1 北京市公安局网络备案 海1101084571
版权所有 北京育灵童科技发展有限公司 Copyright © 2002-2024 www.elight.cn, All Rights Reserved