原型链

65次阅读

共计 1203 个字符,预计需要花费 4 分钟才能阅读完成。

一、创建对象有几种方法

    // 第一种方式:字面量,默认创建对象     
    var a10 = {name:'a10'};             // {name: "a10"}  
    var a11 = new Object({name:'a11'}); // {name: "a11"}

    // 第二种方式:构造函数     
    var a2 = function(){this.name = 'a20'};  
    var a20 = new a2();                 // a2 {name: "a20"}
    
    // 第三种方式:Object.create()       
    var a3 = {name:'a30'};
    var a30 = Object.create(a3);        // {} 之后输入 a30.name 能得到 "a30"

二、实例、构造函数、原型、原型链

2.1 实例

  • 对象就是一个实例,就有 _proto_ 属性。
  • 实例通过 _proto_ 原型链找到 prototype 原型对象,prototype 原型对象的属性被所有实例共享。

2.2 构造函数

  • 通过 new 来创建对象实例。
  • 任何函数都可以作为构造函数。
  • 只要被 new 运算符使用过的函数就是一个构造函数。

2.3 原型

  • 函数都有 prototype 属性,prototype 属性的值就是一个初始化的原型对象。
  • 原型对象有个 constructor_proto_ 属性,constructor 是一个构造函数。
  • Fn.prototype.constructor === Fnconstructor 函数指向构造函数本身。通过 constructor 把原型对象和构造函数关联。)

2.4 原型链

每一个对象都有自己的原型对象,原型对象本身也是对象,原型对象也有自己的原型对象,这样就形成了一个链式结构,叫做 原型链

三、instanceof 的原理


instanceof 主要作用就是判断一个实例是否属于某种类型,实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false

四、new 运算符

// 构造函数
var Fn = function(name) {this.name = name;}
var obj = new Fn('obj');

new 运算符的工作原理:

var newTest = function(fn) {var initObj = Object.create(fn.prototype);
    var obj = fn.call(initObj);
    if(typeof obj === 'object') {return obj;} else {return initObj;}
}
var Fn = function() {// this.name = 'obj', 最后 newTest(Fn)返回的结果完全等同。return {name: 'obj';}
}
newTest(Fn)

原文地址:https://www.artroy.com.cn/art…
更多文章分享:https://www.artroy.com.cn/

正文完
 0

原型链

65次阅读

共计 1977 个字符,预计需要花费 5 分钟才能阅读完成。

原型链概念
每个构造函数内部都会有一个(constructor,prototype 原型对象),而且都会有一个内置树形__proto__属性用于指向创建它函数对象的 prototype 原型,当然原型对象也会有__proto__属性,源源不断的指向关联,就形成了一个圆环,形成了原型链
原型 prototype 对象
函数对象
function f() {
}
console.log(f.prototype)
我们创建了一个函数 f,通过打印它的原型对象,我们会得到一个对象,里面包含一个 constructor 指向自己本身的指针,还有一个内置__proto__属性
console.log(f.prototype.__proto__)

那我们再看看它的内置属性指向了哪里,我们可以很清楚的看到 constructor 指向了 Object,而它还内置了 toString() 和 valueOf() 方法,这到了哪里已经不用我多说了吧
console.log(f.prototype.__proto__.__proto__)
那我们再继续寻找往下找呢,我们会得到 null,此可以得出结论,请看下面图解

普通对象
let obj = {}
console.log(obj.prototype) // undefined
当然普通对象是没有原型对象的
作用
原型链就是为了实现继承
例子
function Father() {
this.name = ‘aaa’
}

Father.prototype.f1 = function () {
alert(this.name)
}

// 子函数 继承父
function Son(name) {
Father.call(this, name)
}

// 我认为继承父
Son.prototype = Object.create(Father.prototype)

// minix 继承多种 Object.assign(1,2,3)
Son.prototype.constructer = Son // 构造器指向

// 重写父方法,改变数据变化,并且不会覆盖父方法,这里称为多态
Son.prototype.f1 = function () {
console.log(this.name)
}

var S1 = new Son()
S1.f1() // 调用 aaa

检查原型和实例的关系
第一种使用 instanceof 操作符
console.log(S1 instanceof Object)//true
console.log(S1 instanceof Father)//true
console.log(S1 instanceof Son)//true

上面检测 S1 这个实例是否属于 Object,Father,Son,结果都返回了 true,有些小伙伴会疑问为什么我 new 的是 Son,它还会属于 Father,因为 Son.prototype = Object.create(Father.prototype) 这段代码已经将父的原型给了子了,并且又 constructer 指向了子函数,这相当于已经继承成功

第二种使用 isPrototypeOf

作用:检测一个对象是否是另一个对象的原型。或者说一个对象是否被包含在另一个对象的原型链中

console.log(Object.prototype.isPrototypeOf(S1)) //true
console.log(Father.prototype.isPrototypeOf(S1)) //true
console.log(Son.prototype.isPrototypeOf(S1)) //true

查找
Function.__proto__ === Function.prototype
每个函数声明之后都会生成一个函数对象,这正如我们说的那样函数的__proto__是指向它自己的原型的
Function.prototype.__proto__ === Object.prototype
函数原型再向上查找是什么,它们直接通过什么连接,当然是__proto__,它指向的则是 Object.prototype
Object.prototype.__proto__ === null
然后再去查找 Object.prototype,它会等于 null,因为已经到达最底层了,这个记住就好
constructor 属性
constructor 属性不影响任何 JavaScript 的内部属性。
instanceof 检测对象的原型链,通常你是无法修改的

constructor 其实没有什么用处,只是 JavaScript 语言设计的历史遗留物。
由于 constructor 属性是可以变更的,所以未必真的指向对象的构造函数,
只是一个提示。不过,从编程习惯上,我们应该尽量让对象的 constructor 指向其构造函数,以维持这个惯例
总结原型和原型链是 JS 实现继承的一种模型原型链是靠__proto__ 形成的,它在其中的作用属于连接的线

正文完
 0

原型链

65次阅读

共计 29 个字符,预计需要花费 1 分钟才能阅读完成。

明天搞起,原型链有哪些知识点呢?望大佬们过来评论哦
睡觉啦 -

正文完
 0