js之原型和原型链

一些知识点相关的面试题和答案

面试官:什么是构造函数
答:构造函数的本质是一个普通函数,他的特点是需要通过new关键字来调用,用来创建对象的实例。所有的引用类型,如[],{},function等都是由构造函数实例化而来。 一般首字母大写。 解析:首字母大写只是约定俗成的规范。首字母小写的函数也可以用作构造函数。

面试官:什么是原型和原型链
答:原型模式是JS实现继承的一种方式。 所有的函数都有一个prototype属性,通过new生成一个对象时,prototype会被实例化为对象的属性。 所有的引用类型都有一个__proto__指向其构造函数的prototype。原型链的话,指的就是当访问一个引用类型时,如果本身没有这个属性或方法,就会通过__proto__属性在父级的原型中找,一级一级往上,直到最顶层为止。 解析:原型链最顶层Object的prototype__proto__指向为null。

面试官:如何理解 constructor 属性
答:所有函数的原型对象都有一个constructor属性指向函数本身。 解析:实例化的对象可以通过[].__proto__.constructor获取到其构造函数。
面试官:描述new 操作符的执行过程
答: 1. 创建一个空对象。 2. 将这个空对象的__proto__指向构造函数的prototype。 3. 将构造函数的this指向这个对象。 4. 执行构造函数中的代码。

面试官:如何判断一个变量是数组类型
答: 使用instanceof关键字 或者constructor属性。 解析:instanceof的原理是判断操作符左边对象的原型链上是否有右边构造函数的prototype属性。

总结性的图表,代码例子或笔试题目和解析,让知识点更容易懂

关于构造函数和原型

构造函数:相当于java中“类”的存在,如原生JS中的 Array, Function, String, Date 等等,都是构造函数。例如 new Date() 通过new操作符进行调用,用来创建一个Date对象的实例。

一个便于理解的栗子,描述js通过原型模式实现继承的过程

function Animal (name) {                 // 构造函数
    this.name = name
}

Animal.prototype.type = 'animal'         // 原型上的属性和方法可以被继承

Animal.prototype.eat = function () {
    console.log('eat')
}

let dog = new Animal('忠犬八公')          // 通过new 调用构造函数创建Animal的实例dog
console.log(dog.name)                    // 输出:忠犬八公
console.log(dog.type)                    // 输出:animal
dog.eat()                                // 输出:eat

console.log(dog.__proto__)               // 输出:{ type:'animal', eat: f, __proto__: ...}  
// dog.__proto__ 指向其构造函数Animal的prototype对象

一个关于原型的实用型例子

function Elem(id) {
    this.elem = document.getElementById(id)
}

Elem.prototype.html = function (val) {
    var elem = this.elem 
    if (val) {
        elem.innerHTML = val
        return this    // 链式编程
    }else{
        return elem.innerHTML
    }
}

Elem.prototype.on = function (type, fn) {
    var elem = this.elem
    elem.addEventListener(type, fn)
}

var div1 = new Elem('div1')
div1.html('灶门碳治郎').on('click', (e) => {
    alert('灶门碳治郎')
})

这个栗子,使用原型将对 dom 节点的操作封装起来,只要创建一个Elem实例就轻松插入 dom 和添加事件监听。

原型链

image.png

所有的引用类型会有一个 proto 属性指向其构造函数的 prototype ,当访问这个引用类型的变量和方法时,会通过 proto 属性一层层往上找。如 [] 不止有构造函数 Array 原型上的方法,还有可以通过原型链找到 Object 原型上的方法。

关于instanceof 和 constructor

instanceof : 判断操作符右边的参数是否在左边的原型链上。 所以 [] instanceof Object 也为true

let obj = {}                                
let arr = []
console.log(typeof(obj))                    // object
console.log(typeof(arr))                    // object
console.log(obj instanceof Array)           // false
console.log(arr instanceof Array)           // true
console.log(obj.constructor === Array)      // false
console.log(arr.constructor === Array)      // true

通过以上代码可以学习通过 instanceof 关键字和 constructor 属性进行数据类型判断的使用方式。

知识延伸
JS究竟是先有Object还是先有Function呢?

console.log(Function instanceof Object)     // 输出:true
console.log(Object instanceof Function)     // 输出:true

Object和Function究竟是什么关系?


image.png

简单理解为:

1.Function 在 Object 的原型链上,因为 Object 是构造函数,他的 proto 指向 Function 的原型
2.Object 在 Function 的原型链上,因为 Function 是构造函数,他的 proto 指向的也是他自己的原型,然而 Function.prototype 本质上是一个对象,所以 Function.prototype.proto 指向 Object.prototype 。

关于链式编程

上述“一个关于原型的实用例子”中,提到了 链式编程 ,在此做简单介绍

function Dog(){
    this.run = function(){
        alert('dog is run...')
        return this                    // 链式编程的关键
    }
    this.eat = function(){
        alert('dog is eat...')
        return this 
    }
    this.sleep = function(){
        alert('dog is sleep...')
        return this 
    }
}
var d1 = new Dog()
d1.run().eat().sleep()

通过以上代码可以看出

链式编程的设计模式就是, 调用的函数的时候,可以基于其返回值继续调用其他方法 。
关键在于方法执行结束后需要有一个供继续调用的返回值,如 this 等。

(网络资源整理而来)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容