JavaScript 3.3 继承与原型链

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

一、JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype )。

该原型对象也有一个自己的原型对象( __proto__ ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。几乎所有 JavaScript 中的对象都是位于原型链顶端的Object 的实例。

二、JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的

原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

示例 1

let f = function () {
   this.a = 1;
   this.b = 2;
}
console.log(f instanceof Function)//true
console.log(f.__proto__ ===Function.prototype)//true
let o = new f();
o是调用构造方法f,生成的实例

console.log(o instanceof f)//true
console.log(o.constructor ===f) // true

f.prototype.b = 3;
f.prototype.c = 4;
不要在 f 函数的原型上直接定义 f.prototype = {b:3,c:4};这样会直接打破原型链
console.log(o.a);
output:1  ,o的自身属性,值为1
console.log(o.b);
output:2  ,o的自身属性值为2,原型上的b会因为同名被遮蔽,成为属性遮蔽
console.log(o.c);
output:4  ,c并不是o的自身属性,当自身没有该属性时,就会往上一层的原型对象上找,
console.log(o.d);
outputundefind ,d不是o的自身属性,上层原型也没有,所以最后输出undefined

整个原型链如下
{a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null


f其实Function对象的实例,所以f有__proto__私有属性指向其构造函数的原型对象
console.log(f.__proto__ ===Function.prototype)//true

同时,f又是一个函数,所以f也有prototype的属性
o.__proto__===f.prototype  //true
实例o的__proto__指向f的prototype原型对象,f.prototype在这里应该当成f的原型
对象,而不应该当成f的prototype属性,尽管他们的值是一样的

 示例2

var o = {a: 1};
var a = ["yo", "whadup", "?"]
var f = function f(){
  return 2;
}

o的原型链o ---> Object.prototype ---> null
a的原型链a ---> Array.prototype ---> Object.prototype ---> null
f的原型链f ---> Function.prototype ---> Object.prototype ---> null

一个对象实例的__proto__指向了其原型对象,其原型对象的__proto__会一直向
上,Object.prototype.__proto__是null,这个实例会继承原型链中的方法

如 o指向了Object.prototype,那么o就有了Object.prototype中的方法

o.hasOwnProperty("a")//true,该方法只会查询实例自身,并不会遍历整个原型链

示例3 继承

"use strict";

class Animal{
    static belong= "china";
    flag = true;
    constructor(age,name){      
        this.age = age;
        this.name = name;
}
     eat(){
            console.log(this.age + "岁的"+ this.name + "会吃食");
}
static run(){console.log(this.name +"会跑")}
}


var o = new Animal(1,"猫");
o.sound = function sound(){console.log(this.name + "的叫声是喵喵")}

Animal.prototype.swim = function swim (){return this.name + "不会游泳"};
var x = new Animal(1,"鸡");

1、static修饰的变量或者方法,不属于实例,而是属于对象的构造函数的

o.constructor.run() === Animal.run() //true

2、没被static修饰的变量是会被实例继承的,如flag

o.hasOwnProperty("flag") === x.hasOwnProperty("flag")//true

3、没被static修饰的方法是属于Animal.prototype原型对象的,如eat


var y = Object.create(o);
以o的原型对象创建一个实例,实例y没有任何私有属性,o的私有属性及方法,以及继承来的
flag属性,都将作为y.__proto__的原型对象的方法和属性



class  Bird extends Animal{

     constructor(age ,name){
        super(age,name)

}
    get allParm(){return this.name + this.age}


    set parm(newname){
        
            this.name = newname

}
}

var a = new Bird(1,"小鸟");
Bird.prototype.bird = "飞";

1、a是Bird对象的实例,它指向的原型对象是Bird
a.__proto__===Bird.prototype //true

2、Bird对象中的get 和 set 都是属于Bird.prototype原型对象中的属性

3、Bird实例会继承Animal中非static修饰的变量
a.hasOwnProperty("flag") //true

示例4 protype与getPrototypeOf

var o = new Foo();
JavaScript 实际上执行的是:

var o = new Object();
o.__proto__ = Foo.prototype;
Foo.call(o);

o.someProp;
它检查 o 是否具有 someProp 属性。如果没有,它会查找 
Object.getPrototypeOf(o).someProp,如果仍旧没有,它会继续查找
Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp。
最后null没有原型对象,所以会返回undefined

Object.getPrototypeOf(o) === o.__proto__//true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值