美文网首页
JS三座大山之原型和原型链

JS三座大山之原型和原型链

作者: 我向你奔 | 来源:发表于2018-02-10 00:34 被阅读91次

构造函数

提到原型就不得不说一下构造函数,我们先来看一个简单的构造函数的例子:

function  Foo (name,age) {
    this.name = name;
    this.age = age;
    //return  this;
}
var f = new Foo ("zhangsan",20);
var f1 = new Foo ("lisi",21);          //创建多个对象

需要说明的是:① 构造函数需以大写字母开头,这样提高了代码的易读性;② return this 那句可有可无,因为它是默认存在的。
在上面的例子中,我们首先创建了一个空对象,再让this指向这个对象,然后执行代码,即给this.name赋值,最后返回this,并将值赋给f和f1。这其实也是new一个对象的过程。
在这里我们稍稍拓展一下构造函数的知识:
① 所有的引用类型都有构造函数
var a = {}其实是var a = new object()的语法糖
var b = []其实是var b = new Array()的语法糖
function Foo() {....}其实是var Foo = new Function()的语法糖
在实际写代码中,我们更推荐使用前者的写法
② 可以使用instanceof判断一个函数是否是一个变量的构造函数,例如

var a = new Array()
alert (a instanceof Array)    // true

同时alert (a instanceof Object)也会返回true,这是因为Array是object的子类。再如

function Test () {}
var a = new Test()
alert (a instanceof Test)      // true 

什么是原型呢?

原型就是一个普通的对象,每个对象都有一个原型(Object除外),原型能存储我们的方法,构造函数创建出来的实例对象能够引用原型中的方法。

Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,有些属性是隐藏的。换句话说,在对象创建时会存在预定义的属性,其中有一个属性就是原型对象。
下面,我们来说说原型规则:
① 所有的引用类型(数组,对象,函数)都具有对象特性,即可自由扩展属性(除了“null”)

var obj = {};
obj.a = 100;
var arr = [];
arr.a = 100;
function fn1 () {}
fn1.a = 100;

② 所有的引用类型(数组,对象,函数)都有一个_proto_(隐式原型)属性,属性值也是一个普通的对象

console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn1.__proto__);

③ 所有的函数,都有 一个prototype(显式原型)属性,属性值也是一个普通的对象

console.log(fn1.prototype);

④ 所有引用类型(数组,对象,函数)的_proto_属性值指向它的构造函数的prototype属性值

console.log(obj.__proto__ === Object.prototype);        
console.log(arr.__proto__ === Array.prototype);   
console.log(fn1.__proto__ === Function.prototype);    

⑤ 当试图得到一个对象的属性时,如果这个对象本身没有这个属性,那么就会去它的_proto_(即构造函数的prototype)中寻找

//构造函数
function Foo(name) {
    this.name = name;
}
Foo.prototype.alertName = function () {
    alert(this.name);
}
//创建实例
var f = new Foo("xiaohui");
f.printName = function () {
    console.log(this.name);
}
//测试
f.printName();
f.alertName();

就刚才的例子,如果想要循环得到对象本身的属性可以通过for in 实现

var item;
for (item in f) {
    //高级浏览器已经在for in中屏蔽了来自原型的属性
    //但是还是加上判断,保证程序的健壮性
    if (f.hasOwnProperty(item)) {
        console.log (item);
    }
} 

如果现在我想要得到f.toString(),我们会发现f和Foo都没有这个方法,于是就去f._proto._proto(Foo.prototype._proto)中寻找,此时找到并调用。

QQ图片20180209232906.jpg
如图,我们要找f的一个属性时首先会在f._proto
中寻找,因为f._proto的属性值是一个对象,所以也有_proto属性,如果没找到,就会去f._proto._proto中找,同理,如果还没找到就继续向上,直到结果为null为止。这个由_proto串起来的直到Object.prototype._proto为null的链就是原型链。

以前一般使用对象的 _proto_属性,ES6推出后,推荐用Object.getPrototypeOf()方法来获取对象的原型 :给定对象的原型。如果没有继承属性,则返回null。

相关文章

  • 前端面试送命题-JS三座大山

    index 前端面试送命题-JS三座大山 __mahao 原型与原型链 说到原型,就不得不提一下构造函数,首先我们...

  • 廖雪峰JS小记

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

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

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

  • JS的__proto__和prototype

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

  • js基础

    js三座大山:原型和原型链 作用域和闭包 异步和单线程引用类型:对象 数组 函数 因为指针引用的是一个空间 所以叫...

  • 前端JS基础一(基础知识)

    基础知识 js基础三座大山 原型 原型链 作用域 闭包 异步 单线程 知识点 1.变量类型:值类型和引用类型(指针...

  • JS三座大山之原型和原型链

    构造函数 提到原型就不得不说一下构造函数,我们先来看一个简单的构造函数的例子: 需要说明的是:① 构造函数需以大写...

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

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

  • js之原型和原型链

    一些知识点相关的面试题和答案 面试官:什么是构造函数答:构造函数的本质是一个普通函数,他的特点是需要通过new关键...

  • 2022前端高频面试题

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

网友评论

      本文标题:JS三座大山之原型和原型链

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