13.JavaScript学习笔记——原型与原型链

原型和原型链

1.原型

1.1 定义

原型是function对象的一个属性(prototype),它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象

Person.prototype.LastName = 'Deng';
Person.prototype.say = function () {
    console.log('hehe');
}
function Person (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}
var person = new Person('xuming', 35, 'male');

1.2 利用原型的特点和概念,可以提取共有属性

原型的共有属性可以减少一定的代码冗余。

function MyCar (color) {
    this.color = color;
    this.name = 'BMW';
    this.height = '1400';
    this.lang = '4900';
    this.weight = 1000;
    this.health = 100;
    this.run = function () {
        this.health --;
    }
}

var car = new MyCar('red');
var car1 = new MyCar('blue');

例如上面代码,Mycar构造函数中,除了color,其他属性都是固定的,每次构造一个新对象都要执行this.xxx = xxx,这些属性可以看作是共有的,因此写到原型里就可以避免每次构造新对象时重复定义属性。

1.3 对象如何查看原型(隐式属性 __proto__)

在构造函数的内部原理中,第一步var this = {},其中{}其实不是空对象,里面含有__proto__ = xxx.prototype

对象.__proto__构造函数.prototype都可以访问原型对象。

function Person () {
            // var this = {
            //     __proto__ = Person.prototype;
            // }
}

var person = new Person();

修改实例.__proto__指向别的对象,会改变该实例的原型对象。

1.4 对象如何查看对象的构造函数(constructor)

由构造函数创建出来的对象存在一个constructor属性指向其构造函数。

对象.constructor会返回该对象的构造函数。

2.理解原型

无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性,函数的prototype属性会指向原型对象;

默认情况下,所有原型对象自动获得一个名为constructor的属性,指回与之关联的构造函数。

每次调用构造函数创建一个新对象,对象内部的[[Prototype]]指针就会被赋值为构造函数的原型对象。

firefox、safari、chrome浏览器会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型。

构造函数、原型对象和实例(调用构造函数创建的对象)是三个完全不同的对象。实例和原型对象之间有直接的联系,但实例和构造函数之间没有。

实例通过__proto__链接到原型对象(它实际上指向隐藏特性[[Prototype]]);构造函数通过prototype属性链接到原型对象,原型对象的constructor属性指回构造函数。

3.原型链

3.1 原型链的构成

每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。

原型本身作为一个对象,内部也存在一个内部指针指向另一个原型,另一个原型也有一个指针指向另一个构造函数。

以此类推,就在实例和原型之间构造了一条原型链

3.2 原型搜索机制

原型链扩展了原型搜索机制。

在读取实例上的属性时,首先会在实例上搜索这个属性。如果没有找到,则会继承搜索实例的原型。

在通过原型链实现继承之后,搜索就可以继承向上,搜索原型的原型。

3.3 原型链的终端(默认原型)

绝大多数对象的最终都会继承自Object.prototype

默认情况下,所有引用类型都继承自Object,这也是通过原型链实现的。任何函数的默认原型都是一个Object的实例。

3.4 Object.create()

Object.create()方法也可以创建一个新对象,使用现有的对象来提供新创建对象的__proto__

特殊地,Object.create()括号中不仅可以放现有对象,还可以放null。

Object.create(null);创建出的新对象没有任何属性,这意味着这个新对象也没有__proto__,所以它不会继承自Object

此时人为给对象添加__proto__属性是没有效果的。

document.write()实质上是打印括号中内容的.String。

var obj = Object.create(null);
document.write(obj);  //报错

4.函数重写

原型链中的函数重写:

用重名不同功能的函数覆盖继承来的函数。

例如,在Object的原型中,有一个toString函数,而在包装类Number、String、Boolean、Array中各自定义了各自的toString函数,在使用包装类时,调用toString则使用的是重写后的功能。

tips: javascript可正常计算的范围,小数点前16位,后16位。

0.1 + 0.2 == 0.3为false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值