美文网首页javascript
js原型、原型链

js原型、原型链

作者: YINdevelop | 来源:发表于2017-12-13 16:47 被阅读24次

1.函数也是对象

有时我们会好奇为什么能给一个函数添加属性,函数难道不应该就是一个执行过程的作用域吗?

var fn=function(){
    this.name='手机'
}
fn.age=11
console.log(fn.age)  //11

console.log(fn)
// function(){
//  this.name='手机'
// }

其实,在JS里,函数就是一个对象,对象里面保存键值对。本例中fn为属性,属性值是函数的字符串,当调用函数执行时,js会将该字符串解析成可执行语句。

2.构造函数和普通函数的区别

function fn(){
    this.name='手机'
    console.log(this)
}
fn()

//此时这里面的this表示window

var m=new fn()

//此时this表示m对象。
  • 用关键词new 调用的函数叫做构造函数
  • 虽然没有硬性规定,为了和普通函数区分,构造函数一般首字母大写。
  • 构造函数里的this指向通过构造函数创建出来的新对象。

3.函数和原型的关系

function Fn(name){
    this.name=name
    this.kind='电子产品'
}
var m1=new Fn('手机');
var m2=new Fn('电脑');

结果会生成两个m1,m2对象。

m1={
    name:'手机',
    kind:'电子产品'
}
m2={
    name:'电脑',
    kind:'电子产品'
}
//每一个实例对象,都有自己的属性和方法的副本。修改任何一个都不会影响另一个。
这不仅无法做到数据共享,也是极大的资源浪费。

function Fn(name){
    this.name=name
}
Fn.prototype = { kind : '电子产品' };
var m1=new Fn('手机');
var m2=new Fn('电脑');

结果会生成两个m1,m2对象。

m1={
    name:'手机',
    kind:'电子产品'
}
m2={
    name:'电脑',
    kind:'电子产品'
}
//kind属性放在prototype对象里,是两个实例对象共享的。只要修改了prototype对象,
就会同时影响到两个实例对象。
  • JS里,我们创建的每一个函数都有一个prototype(原型)属性,这个属性指一个——用于包含该对象所有实例的共享属性和方法——的对象。
  • 原型对象同时包含一个指针指向这个这个函数,这个指针就是constructor,这个函数也就是构造函数。

了解了原型和constructor指针后,我们通过一个例子以及一张图来进一步了解这两者的关系。

function Person(){
    this.age=10
}

Person.prototype.name = 'Nicholas';
Person.prototype.age = 24;
Person.prototype.sayAge = function () {
    alert(this.age);
};
1.png

4.原型和实例的关系

function Person(){
    this.age=10
}

Person.prototype.name = 'Nicholas';
Person.prototype.age = 24;
Person.prototype.sayAge = function () {
    alert(this.age);
};

//实例
var person1 = new Person('Lee');
var person2 = new Person('Lucy');

我们新建了两个实例person1和person2,这些实例的内部都会包含一个指向其构造函数的原型对象的指针(内部属性),不是对外访问的API,这个指针叫[[Prototype]],在ES5的标准上没有规定访问这个属性,所以在浏览器上是不能console出这个属性的,会报错。但是大部分浏览器通过proto的属性来访问它,成为了实际的通用属性,于是在ES6的附录里写进了该属性。

prototype和proto都叫原型,如果非要区分,prototype我们称为显示原型,proto我们称为隐式原型。

22.png
person1.__proto__ == Person.prototype // true

4.原型链

function Person(){
    this.age=10
}

Person.prototype.name = 'Nicholas';
Person.prototype.age = 24;
Person.prototype.sayAge = function () {
    alert(this.age);
};

//实例
var person1 = new Person();

前面的demo中我们举了一个类似这样的例子。
我们尝试输出实例的属性。

person1.age; // 10
person1.name; // Nicholas
person1.toString; // function toString() { [native code] }
person1

我们输出一下person1试试

im.jpg

从上例中,我们可以看出,Person有自己的原型,即Person.prototype,同样Person.prototype也有自己的原型,即Person.prototype.proto属性,我们输出下试试。

console.log(Person.prototype)
console.log(Person.prototype.__proto__)
console.log(Person.prototype.__proto__.__proto__)

结果如下。

img1.jpg

我们来总结下原型链。

当我们访问实例对象的一个属性时候,如果不存在,就去实例的原型对象里面找,这个原型对象也有自己的原型对象。就这样一直找就构成了我们常说的线性原型链。

上面代码的age来自于自身属性,name来自于原型属性,toString( )方法来自于Person原型对象的原型Object的原型。当我们访问一个实例属性的时候,如果没有找到,我们就会继续搜索实例的原型,如果还没有找到,就递归搜索原型链直到原型链末端。

我们来验证下

Person.prototype.__proto__ == Object.prototype // true

继续深入验证

Person.__proto__ == Function.prototype // true
Function.prototype.__proto__ == Object.prototype // true

我们会发现Person是Function对象的实例,Function是Object对象的实例,Person原型是Object对象的实例。

最后,奉上一张原型大图

33.jpg
  • 构造函数和对象原型一一对应,他们与实例一起作为三要素构成了三面这幅图。最左侧是实例,中间是构造函数,最右侧是对象原型。
  • 最最右侧的null告诉我们:Object.prototype.proto = null,也就是Object.prototype是JS中一切对象的根源。其余的对象继承于它,并拥有自己的方法和属性。

最后的最后,说了这么多,实际怎么用?大家下去可以看一下,js面向对象的三大特性:
封装、继承、多态

原型链主要用于继承特性。
参考来源https://segmentfault.com/a/1190000011389965

相关文章

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • 关于JS中的原型和原型链

    目录 关于js 对象和原型 原型链 基于原型链的继承 参考资料ECMAScript 6 入门JavaScript原...

  • js_继承及原型链等(四)

    js_继承及原型链等(三) 1. 继承 依赖于原型链来完成的继承 发生在对象与对象之间 原型链,如下: ==原型链...

  • JS原型链

    1什么是JS原型链? 通过__proto__属性将对象与原型对象进行连接. 1.1 JS原型链的作用? 组成的一个...

  • 从实现角度分析js原型链

    从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,...

  • web前端面试之js继承与原型链(码动未来)

    web前端面试之js继承与原型链(码动未来) 3.2.1、JavaScript原型,原型链 ? 有什么特点? 每个...

  • 2022前端高频面试题

    JS相关 1.原型和原型链是什么 原型和原型链都是来源于对象而服务于对象的概念js中引用类型都是对象,对象就是属性...

  • 再来看一次JS继承

    原型链继承 理解原型链的概念 用一张图来理解原型链再合适不过了。 总结概括JS红宝书上对原型链的概念:每个函数都有...

网友评论

    本文标题:js原型、原型链

    本文链接:https://www.haomeiwen.com/subject/bmkzixtx.html