JS的原型链和继承

1.JavaScript中每一个对象都有一个特殊的内置属性[[prototype]],这个特殊的对象可以指向另一个对象

浏览器给我们提供了一个API 可以查看这个原型对象 __proto__

我们每个对象中都有一个[[prototype]],这个属性可以称之为对象的原型(隐式原型)

2. 原型的作用

当从一个对象中获取某一个属性时,会触发[[get]]操作

// 1. 当前对象中去查找对应的属性,如果找到就直接使用

// 2. 如果没有找到,就会沿着它的原型去查找[[prototype]]

3. 函数的原型函数因为本身它是一个函数,所以它还会多出来一个显示原型属性:prototype

通过构造函数创建出来的对象,这个对象的内部的[[prototype]]属性会被赋值为该构造函数的prototype属性

function foo() {
}

var f1 = new foo()
var f2 = new foo()

console.log(f1.__proto__ === foo.prototype)  // true
console.log(f2.__proto__ === foo.prototype)  // true

在内存中f1、f2对象的__proto__都指向了foo函数的显示原型对象prototype

 

原型链:从一个对象上获取属性,如果当前对象中没有获取到就会去它的原型上获取:

var obj = {
    name:  "hgf",
    age: 18
}

obj.__proto__ = {
}

obj.__proto__.__proto__ = {
    address: "广东省"
}

console.log(obj.address)  // 广东省

 4. Object的原型

obj.__proto__.__proto__的尽头 其实是 //[Object: null prototype] {}

这个原型就是我们的最顶层原型了

从Object直接创建出来的对象的原型都是[Object: null prototype] {}

[Object: null prototype] {}的特殊之处:

①该对象有原型属性__proto__ :null  指向null,也就是已经是顶层原型了;

②该对象上有很多默认的属性和方法;

Object的顶层原型来自哪里

即为Object.prototype

var obj = {
    name: "hgf",
    age: 18
}

console.log(obj.__proto__)  // [Object: null prototype] {}
console.log(Object.prototype)  // [Object: null prototype] {}
console.log(obj.__proto__ === Object.prototype)  //true

会发现Object是所有类的父类

5. 原型内容的补充 

对象的方法

①hasOwnProperty()  // 判断是否有某一个属于自己的属性(不是在原型上的属性)

var obj = {
    name: "hgf",
    age: 20
}

var info = Object.create(obj, {
    address: {
        value: "广东省",
        enumerable: true
    }
})

console.log(info.hasOwnProperty("address"))  // true
console.log(info.hasOwnProperty("name"))  //false

②in/for in 操作符  // 判断某个属性是否在某个对象或对象的原型上

// in 操作符: 不管在当前对象还是原型中返回的都是true
console.log("address" in info)
console.log("name" in info)

// // for in
for (var key in info) {
  console.log(key)
}

③instanceof  // 用于检测构造函数的prototype,是否出现在某个实例对象的原型链上

function createObject(o) {
  function Fn() {}
  Fn.prototype = o
  return new Fn()
}

// 封装的继承函数
function inheritPrototype(SubType, SuperType) {
  SubType.prototype = createObject(SuperType.prototype)
  Object.defineProperty(SubType.prototype, "constructor", {
    enumerable: false,
    configurable: true,
    writable: true,
    value: SubType
  })
}


function Person() {

}

function Student() {

}

// 让Student继承自Person
inheritPrototype(Student, Person)

console.log(Person.prototype.__proto__)

var stu = new Student()
console.log(stu instanceof Student) // true
console.log(stu instanceof Person) // true
console.log(stu instanceof Object) // true  Objcet是所有对象的父类

④isPrototypeof  // 用于检测某个对象,是否出现在某个实例对象的原型链上

function Person() {

}

var p = new Person()

console.log(p instanceof Person)  // true
console.log(Person.prototype.isPrototypeOf(p))  // true

// 
var obj = {
  name: "why",
  age: 18
}

var info = Object.create(obj)

// console.log(info instanceof obj)   会报错  因为obj不是一个构造函数
console.log(obj.isPrototypeOf(info))  // true

对象-函数-原型之间的关系

函数的prototype与proto,函数本身也是一个对象(因为函数相当于 new Function()创建),之间的关系

function Foo() {
}

// Foo作为一个函数,那么它本身会有一个显示原型对象:Foo.prototype
// Foo.prototype来自哪里
// 答案:创建了一个函数,Foo.prototype = {constructor: Foo}  //是Foo函数的显示原型,是一个对象


// Foo作为一个对象  因为函数相当于 new Function()创建,那么它会有一个隐式原型对象:Foo.__proto__
// Foo.__proto__来自哪里
// 答案: new Function() Foo.__proto__ = Function.prototype
// Function.prototype = {constructor: Function}

Foo.prototype === Foo.__proto__   //false

 Function.prototype === Function.__proto__(Function最特殊的地方)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值