JavaScript原型与原型链

5 篇文章 0 订阅
1 篇文章 0 订阅

原型与原型链

JavaScript万物皆由对象,一切皆空!!!

1.设计模式

  1. 设计模式概念:软件开发人员在软件开发过程中面临的一般问题的解决方案

  2. 原型模式:原型模式是一种创建型设计模式, 用于创建重复的对象,同时又能保证性能

1.1面向对象

  1. 特征:继承、封装、多态

  2. java和js继承的区别:

    继承:继承属于类与类之间的关系,继承的目的是为了实现数据共享;

    js:是一种基于原型的面向对象的编程语言,js通过构造函数模拟类,通过原型来实现继承;

    java:是一种面向对象的编程语言,类实现继承;

2.原型链和原型

2.1理论

prototype、_proto_
  1. prototype(显式原型):所有的函数的一个属性prototype,这个属性指向函数的原型对象;
  2. _proto_(隐式原型):每个对象都有一个__proto__属性,指向该实例对象对应的原型对象;
  3. constructor:原型对象有一个constructor属性,指向该原型对象对应的构造函数
构造函数、实例、原型对象
  1. 构造函数:用来创建对象的函数;

  2. 实例:实例就是通过构造函数创建出来的对象;

  3. 原型:每个函数在被创建的时候,都会默认有一个prototype属性,prototype的属性值是一个对象,也就是构造函数的原型;

/**
①写一个函数:
*/
function Bird(kind,color){
    this.kind=kind;
    this.color=color;
};
console.log(Bird.prototype,'原型对象');//原型对象
console.log(Bird.prototype.constructor,'指向函数');//指向函数
/**
②构建一个实例:
*/
let a=new Bird('猫头鹰','灰色');
console.log(a,'实例对象');//实例对象
console.log(a.__proto__,'指向原型对象');//指向原型对象
console.log(a.__proto__.constructor,'指向函数');//指向函数

/**
③构造函数、原型、实例
*/
console.log(a.__proto__===Bird.prototype);
console.log(a.__proto__.constructor===Bird.prototype.constructor);
  1. 关系图:
    在这里插入图片描述

2.2找原型链

2.2.1数据类型
数组
/**
创建数组实例
*/
let arr=new Array(1,8,0);
console.log(arr);
console.log(Array.prototype,'构造函数的原型对象');
//①查看实例arr的原型
console.log(arr.__proto__,'原型');
console.log(arr.__proto__.constructor,'原型的指向');//Array
console.log(arr.__proto__===Array.prototype);
//②查看实例arr的原型的原型
console.log(arr.__proto__.__proto__,'原型的原型');
console.log(arr.__proto__.__proto__.constructor,'原型的原型的指向');//Object
console.log(arr.__proto__.__proto__===Object.prototype);
//③原型链的终点
console.log(arr.__proto__.__proto__.__proto__,'终点');

在这里插入图片描述

字符串
/**
创建字符串实例
*/
let str=new String('43');
console.log(str);
console.log(String.prototype,'构造函数的原型对象');
//①查看实例str的原型
console.log(str.__proto__,'原型');
console.log(str.__proto__.constructor,'原型的指向');
console.log(str.__proto__===String.prototype);//String
//②查看实例str的原型的原型
console.log(str.__proto__.__proto__,'原型的原型');
console.log(str.__proto__.__proto__.constructor,'原型的原型的指向');//Object
console.log(str.__proto__.__proto__===Object.prototype);
//③原型链的终点
console.log(str.__proto__.__proto__.__proto__,'终点');

在这里插入图片描述

DOM
<body>
    <div>div标签</div>
    <p>P标签</p>
    <a href="#">a标签</a>
    <script>
        let div = document.querySelector('div');
        let p = document.querySelector('p');
        let a = document.querySelector('a');
        //①找原型
        console.log(div.__proto__, 'div第一层的原型');
        console.log(p.__proto__, 'p的原型');
        console.log(a.__proto__, 'a的原型');
        //②原型的指向
        console.log(div.__proto__.constructor, 'div的原型指向');
        console.log(p.__proto__.constructor, 'p的原型指向');
        console.log(a.__proto__.constructor, 'a的原型指向');
        //③原型的原型
        console.log(div.__proto__.__proto__, 'div第二层原型');
        console.log(p.__proto__.__proto__, 'p的原型的原型');
        console.log(a.__proto__.__proto__, 'a的原型的原型');
        //④原型的原型的指向
        console.log(div.__proto__.__proto__.constructor, 'div的原型的原型指向');
        //⑤原型的原型的原型
        console.log(div.__proto__.__proto__.__proto__, 'div第三层原型');
        console.log(div.__proto__.__proto__.__proto__.__proto__, 'div第四层原型');
        console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__, 'div第五层原型');
        console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__, 'div第六层原型');
        console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__, 'div第七层原型');
    </script>
</body>

在这里插入图片描述

2.2.2 instanceof

语法:object instanceof constructor

作用:用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

/**
①字符串
*/
let a='abc';
let b=new String('abc');
console.log(a==b)//true;
console.log(a===b)//false;
console.log(b instanceof Object);
console.log(a instanceof Object);
console.log(a instanceof String);
console.log(b instanceof String);
/**
②数组
*/
let a=[1,8,0];
let b=new Array(1,8,0);
console.log(b instanceof Object);
console.log(a instanceof Object);
console.log(b instanceof Array);
console.log(a instanceof Array);
/**
②null和undefined
*/
let a=null;
let b=undefined;
console.log(b instanceof Object);
console.log(a instanceof Object);
/**
ECMAScript 规范认为(https://262.ecma-international.org/5.1/#sec-4.3.9)
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
*/
console.log(a==b);//true
ToObject原则(补充)

JS中使用字符串可以直接赋值字符串字面量,或者是new String("252")

那这两中定义字符串的区别在哪?

当我们尝试访问一个primitive值的属性时,JS引擎内部会调用一个内置[[toObject]] 方法,将字面量的”252”转为一个[[PrimitiveValue]]为”252”的String对象,然后从其原型链中尝试查找需要访问的属性,使用结束后再释放掉这个String对象。

let a='22';
let b=new String('22');
console.log(a);
console.log(b);

简而言之就是把构造函数创建的字符串通过ToObject算法转换成了字面量定义的值。

ECMAScript 规范规范:https://tc39.es/ecma262/
在这里插入图片描述

题目应用
function Box() { this.name = '我是Box'; }
function Desk() { this.age = 100; }
Desk.prototype = new Box();//通过原型链继承     
var desk = new Desk();
console.log(desk instanceof Box);//true
console.log(Desk.prototype instanceof Box);//true
console.log(Desk.prototype instanceof Desk);//false

在这里插入图片描述

3总结

原型继承

  1. 概念:把父对象作为子对象构造函数的原型;

  2. 代码演示:

    //父对象
    var parent={
      home:{
        plate:'150号',
        stree:'香榭丽舍大道'
      },
      money:1000000
    }
    //子对象
    function Son(name,age){
      this.name=name;
      this.age=age;
    }
    var result=new Son('zzh',18);
    console.log(result,'没继承parent时候的实例对象');
    /**
    原型继承
    */
    Son.prototype=parent;
    Son.prototype.construct=Son;//可选
    var result=new Son('zzh',18);
    //Son.prototype.constructor=Son;//可选
    console.log(result,'已经继承parent属性的实例对象');
    console.log(Son.prototype.constructor);
    

    在这里插入图片描述

访问原型链的规则

就近原则:对象先访问自己的属性,自己没有就找原型的,原型没有就找原型的原型,一直到原型链终点null,如果还找不到,属性则获取undefined。

function Person(name,age){
    this.name=name;
    this.age=age
};
Person.prototype.country='中国';
Person.prototype.eat=function(){
    console.log('吃零食')
}
let p1=new Person('张三',18);

/**
得到的结果
*/
console.log(p1.name);
console.log(p1.age);
console.log(p1.country);
console.log(p1.height);
p1.eat();
p1.learn();

5问题

  1. 原型是什么?

    每个函数都有一个属性prototype(显式原型),这个属性指向函数的原型对象;每个对象都有一个属性_proto_(隐式原型),这个属性指向该实例对象对应的原型对象;

  2. 原型链是什么?原型链的作用?

    JS中万物皆对象,对象与对象之间有关联,当我们寻找一个对象的属性的时候,会先去找它自己的属性有没有这个属性,如果自己没有,就会顺着它的原型属性上面找,看有没有这个属性,如果没有,则继续找下去,这个关系就形成了一条链式,专业术语叫原型链,而原型链是JS用来实现继承的一种方式;

  3. 为什么[] instanceof Object会等于true?

    因为instanceof就是在原型链上面找有没有出现过,如果出现过为true,反之false,而在数组的原型链中,第二层原型链中出现过对象构造函数,所以[] instanceof Object等于true;

  4. 原型链访问原则是什么?终点是什么?

    原型链的访问原则就是,先去找对象本来的属性,如果没有出现再去找原型上面的属性,如果还是没有找到,那就去找原型的原型属性,最后找到null的时候,原型链访问结束;原型链的终点是null;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值