攻略前端面试官(三):JS的原型和原型链
本文在个人主页同步更新~
背就完事了
介绍:一些知识点相关的面试题和答案
使用姿势:看答案前先尝试回答,看完后把答案收起来检验成果~
面试官:什么是构造函数
答:构造函数的本质是一个普通函数,他的特点是需要通过new关键字来调用,用来创建对象的实例。所有的引用类型,如[],{},function等都是由构造函数实例化而来。一般首字母大写。
解析:首字母大写只是约定俗成的规范。首字母小写的函数也可以用作构造函数。
面试官:什么是原型和原型链
答:原型模式是JS实现继承的一种方式。所有的函数都有一个prototype属性,通过new生成一个对象时,prototype会被实例化为对象的属性。所有的引用类型都有一个__proto__指向其构造函数的prototype。原型链的话,指的就是当访问一个引用类型时,如果本身没有这个属性或方法,就会通过__proto__属性在父级的原型中找,一级一级往上,直到最顶层为止。
解析:原型链最顶层Object的prototype的__proto__指向为null。
面试官:如何理解constructor属性
答:所有函数的原型对象都有一个constructor属性指向函数本身。
解析:实例化的对象可以通过[].__proto__.constructor获取到其构造函数。
面试官:描述new 操作符的执行过程
答:
- 创建一个空对象。
 - 将这个空对象的
__proto__指向构造函数的prototype。 - 将构造函数的
this指向这个对象。 - 执行构造函数中的代码。
 
面试官:如何判断一个变量是数组类型
答: 使用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和添加事件监听。
原型链
所有的引用类型会有一个__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究竟是什么关系,这个问题一度困扰着我,直到我看到了这张图
简单理解为:
Function在Object的原型链上,因为Object是构造函数,他的__proto__指向Function的原型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等。 
Kane -- 一切都是命运石之门的选择
攻略前端面试官(三):JS的原型和原型链的更多相关文章
- 攻略前端面试官(一):JS的数据类型和内存机制浅析
		
原文地址:http://rainykane.cn/2019/09/29/与K_K君一起攻略前端面试官(一):JS的数据类型和内存机制浅析/ 背就完事了 介绍:一些知识点相关的面试题和答案 使用姿势:看 ...
 - 老李分享:《Linux Shell脚本攻略》 要点(三)
		
老李分享:<Linux Shell脚本攻略> 要点(三) 1.生产任意大小的文件 [root@localhost dd_test]#[root@localhost dd_test]# ...
 - 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)
		
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...
 - 前端面试送命题-JS三座大山
		
前言 本篇文章比较适合3年以上的前端工作者,JS三座大山分别指:原型与原型链,作用域及闭包,异步和单线程. 原型与原型链 说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子: functi ...
 - 前端面试:谈谈 JS 垃圾回收机制
		
摘要: 不是每个人都回答的出来... 最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B 格 ...
 - 阿里巴巴Web前端面试的一道JS题目,求解答!!!
		
题目大概是这种: function outer(){ return inner; var inner = "a"; function inner(){}; inner = 9; } ...
 - web前端面试官挖的那些坑(js)
		
题目1: function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () ...
 - 前端面试:Vue.js常见的问题
		
摘自今日头条用户:代码开发 原文链接: https://www.toutiao.com/a6683120112255369732/?tt_from=mobile_qq&utm_campaign ...
 - web前端面试系列 一 js闭包
		
一.什么是闭包? JavaScript高级程序设计第三版: 闭包是指有权访问另一个函数作用域中的变量的函数. 在js中定义在函数内部的子函数能够访问外部函数定义的变量,因此js内部函数就是一个闭包. ...
 
随机推荐
- ubuntu触摸板双指滑动,页面滚动方向
			
setting——mouse & Touchpad——Natural scrolling 跟我的另一台本子一样了-
 - Robot Framework自动化测试环境搭建
			
robotFramework是一个通用的自动化测试框架来进行验收测试和验收测试驱动开发模式,它具有易于使用的表格的测试数据和关键字测试驱动方法,其测试功能可通过实现与python或java的测试库进行 ...
 - ES6 Map 原理
			
ES6的Map的键可以是任意的数据结构,并且不重复. 那么map的底层原理是啥呢? Map利用链表,hash的思想来实现. 首先,Map可以实现删除,而且删除的数据可以是中间的值.而链表的优势就是在中 ...
 - [FPGA]Verilog实现寄存器LS374
			
目录 想说的话... 正文 IC介绍 电路连接图 功能表 逻辑图 实验原理 单元实现_D触发器 整体实现(完整代码) 想说的话... 不久前正式开通了博客,以后有空了会尽量把自己学习过程中的心得或者感 ...
 - GeoServer 修改端口
			
准备内容 安装环境:win10*64位专业版 安装文件:geoserver-2.15.2 操作步骤 1.找到文件夹下的start.ini,并用记事本打开 2.找到jetty.port,修改为自己需要的 ...
 - 20191019-3 alpha week 2/2 Scrum立会报告+燃尽图 03
			
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9799 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 ...
 - Github远程库与Git本地库连接
			
Github远程库与Git本地库连接 以下有任何[]符号只是将内容扩起,输入命令不需要将[]加入 创建SSH Key 用户主目录有.ssh->id_rsa和id_rae.pub->直接跳过 ...
 - linux bash编程之函数和循环控制
			
函数:实现独立功能的代码段 函数只有在调用时才会执行 语法一: function F_NAME{ 函数体 } 语法二: F_NAME() { 函数体 } 函数的返回值: 默认函数返回值:函数执行状态返 ...
 - JavaScript 数组学习总结
			
类数组转数组 ES5解决方案 let arr = Array.prototype.slice.call(arrlike) ES6解决方案 let arr = Array.from(arrlike) / ...
 - SpringMVC请求参数接收总结(一)
			
前提 在日常使用SpringMVC进行开发的时候,有可能遇到前端各种类型的请求参数,这里做一次相对全面的总结.SpringMVC中处理控制器参数的接口是HandlerMethodArgumentRes ...