JavaScriptの研究ノート(XII)のプロトタイプ

いつもご覧見つけることは困難ではない、実際には、無料の再オーダーのビットを活用するために、最近つまずい前ルックプロトタイプとプロトタイプチェーン、

ここでは、ステップバイステップで、完全に明確なプロトタイプとプロトタイプチェーンバーに従ってください

1、試作品

  • オブジェクトのインスタンスがありconstructor、それにプロパティをコンストラクタ
function Person(name) {
    this.name = name
}
var person = new Person('Steve') // 自定义构造函数
var string = new String('Hello') // 原生的构造函数

console.log(person.constructor === Person)
console.log(string.constructor === String)

/*
 * 执行结果:
 * true
 * true
**/
  • (コンストラクタを含む)関数オブジェクトが持つprototype属性、関数プロトタイプオブジェクトポイント

    プロトタイプオブジェクトconstructor関数自体を指す属性、

function Person(name) {
    this.name = name
}
var person = new Person('Steve') // 自定义构造函数
var string = new String('Hello') // 原生的构造函数

console.log(Person.prototype.constructor === Person)
console.log(String.prototype.constructor === String)

/*
 * 执行结果:
 * true
 * true
**/
  • それぞれのターゲットは持って[[prototype]]そのプロトタイプオブジェクトのコンストラクタを指し、私有財産を、このプロパティがアクセスすることを許可されていません

    (クロム等)、一部のブラウザでは提供して__proto__プロパティがアクセスするために使用された[[prototype]]私有財産を

function Person(name) {
    this.name = name
}
var person = new Person('Steve') // 自定义构造函数
var string = new String('Hello') // 原生的构造函数

console.log(person.__proto__ === Person.prototype)
console.log(string.__proto__ === String.prototype)
console.log(Person.__proto__ === Function.prototype)
console.log(String.__proto__ === Function.prototype)

/*
 * 执行结果:
 * true
 * true
 * true
 * true
**/
  • コンストラクタのconstructor属性が向けられているFunction__proto__プロパティが向けられていますFunction.prototype

    コンストラクタが通じているのでnew Function作成するには、彼らはオブジェクトと関数を含む関数オブジェクトの例であり、

function Person(name) {
    this.name = name
}

console.log(Person.constructor === Function)
console.log(Person.__proto__ === Function.prototype)
console.log(String.constructor === Function)
console.log(String.__proto__ === Function.prototype)

console.log(Function.constructor === Function)
console.log(Function.__proto__ === Function.prototype)
console.log(Object.constructor === Function)
console.log(Object.__proto__ === Function.prototype)

/*
 * 执行结果:
 * true
 * true
 * true
 * true
 * true
 * true
 * true
 * true
**/
  • またObject、他のコンストラクタのprototypeプロパティの__proto__属性が向けられていますObject.prototype

    そして、のプロパティ属性ポイントObjectprototype__proto__null

function Person(name) {
    this.name = name
}

console.log(Person.prototype.__proto__ === Object.prototype)
console.log(String.prototype.__proto__ === Object.prototype)

console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)

/*
 * 执行结果:
 * true
 * true
 * true
 * true
**/

それは少し複雑に見えますが、最後に、画像をまとめるために、しかし限り、私たちは法律を見つけると、非常にシンプルになります

カテゴリーはあなたに、注意を払うを見てみることをお奨めがある場合constructorがあるプロパティ、prototypeプロパティがあり、__proto__プロパティは、

2、プロトタイプチェーン

(1)原型链

上面我们说过,所有对象都有 __proto__ 属性,并且这个 __proto__ 属性指向一个原型对象

因为原型对象也是对象,这个原型对象也有 __proto__ 属性,我们把这种关系称为原型链

(2)属性访问

当需要访问一个对象的属性时,首先从该对象开始查找,如果能够找到,那么到此返回

如果没有找到,就在该对象的 __proto__ 属性指向的原型对象中继续查找,如果能够找到,那么到此返回

如果没有找到,那么一直往上查找原型对象,直至 __proto__ 属性指向 null,也就是原型链的顶端

若原型链上的所有原型对象都没有该属性,则返回 undefined

function Person(name) { this.name = name }
Person.prototype.getName = function() { return this.name }
var person = new Person('Steve')

var name = person.getName() // 在 Person.prototype 中找到
var description = person.toString() // 在 Object.prototype 中找到
var age = person.age // 在原型链中无法找到

console.log(name)
console.log(description)
console.log(age)

/*
 * 执行结果:
 * Steven
 * [object Object]
 * undefined
**/

(3)属性检测

  • in 操作符:检测属性是否在对象的原型链上
  • hasOwnProperty 方法:检测属性是否来自对象本身
function Person(name) { this.name = name }
Person.prototype.getName = function() { return this.name }
var person = new Person('Steve')

console.log('age' in person)
console.log('name' in person)
console.log('getName' in person)
console.log('toString' in person)

console.log(person.hasOwnProperty('age'))
console.log(person.hasOwnProperty('name'))
console.log(person.hasOwnProperty('getName'))
console.log(person.hasOwnProperty('toString'))

/*
 * 执行结果:
 * false
 * true
 * true
 * true
 * false
 * true
 * false
 * false
**/

3、为什么要使用原型

JavaScript 中的继承是基于原型的,原型的作用在于不同实例对象之间可以共享数据,节省内存

function Person(name) { this.name = name }
Person.prototype.getName = function() { return this.name }
var person1 = new Person('Steve')
var person2 = new Person('Steven')

// 不同实例对象 person1 和 person2 都可以使用在 Person.prototype 上定义的 getName(共享数据)
// 从而避免在每个实例对象上都要重复定义 getName(节约内存)
var name1 = person1.getName()
var name2 = person2.getName()
console.log(name1)
console.log(name2)

/*
 * 执行结果:
 * Steve
 * Steven
**/

4、要怎么样使用原型

为一个对象添加原型有三种方式,分别是 new 关键字、class 关键字和 Object.create 方法

其中,class 关键字其实是 new 关键字的语法糖

  • new 关键字
function Person(name) {
    this.name = name
}
Person.prototype.getName = function() {
    return this.name
}

var person = new Person('Steve')
var prototype = Object.getPrototypeOf(person)
console.log(prototype)
  • class 关键字
class Person {
    constructor(name) {
        this.name = name
    }
    getName() {
        return this.name
    }
}

var person = new Person('Steve')
var prototype = Object.getPrototypeOf(person)
console.log(prototype)
  • Object.create 方法
var object = {
    name: 'Steve',
    getName: function() {
        return this.name
    }
}

var person = Object.create(object)
var prototype = Object.getPrototypeOf(person)
console.log(prototype)

【 阅读更多 JavaScript 系列文章,请看 JavaScript学习笔记

おすすめ

転載: www.cnblogs.com/wsmrzx/p/12199295.html