本文在个人主页同步更新~

背就完事了

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

使用姿势:看答案前先尝试回答,看完后把答案收起来检验成果~

面试官:什么是构造函数

答:构造函数的本质是一个普通函数,他的特点是需要通过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和添加事件监听。

原型链

所有的引用类型会有一个__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究竟是什么关系,这个问题一度困扰着我,直到我看到了这张图

简单理解为:

  1. FunctionObject的原型链上,因为Object是构造函数,他的__proto__指向Function的原型
  2. ObjectFunction的原型链上,因为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()

通过以上代码可以看出

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

Kane -- 一切都是命运石之门的选择

攻略前端面试官(三):JS的原型和原型链的更多相关文章

  1. 攻略前端面试官(一):JS的数据类型和内存机制浅析

    原文地址:http://rainykane.cn/2019/09/29/与K_K君一起攻略前端面试官(一):JS的数据类型和内存机制浅析/ 背就完事了 介绍:一些知识点相关的面试题和答案 使用姿势:看 ...

  2. 老李分享:《Linux Shell脚本攻略》 要点(三)

    老李分享:<Linux Shell脚本攻略> 要点(三)   1.生产任意大小的文件 [root@localhost dd_test]#[root@localhost dd_test]# ...

  3. 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

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

    前言 本篇文章比较适合3年以上的前端工作者,JS三座大山分别指:原型与原型链,作用域及闭包,异步和单线程. 原型与原型链 说到原型,就不得不提一下构造函数,首先我们看下面一个简单的例子: functi ...

  5. 前端面试:谈谈 JS 垃圾回收机制

    摘要: 不是每个人都回答的出来... 最近看到一些面试的回顾,不少有被面试官问到谈谈JS 垃圾回收机制,说实话,面试官会问这个问题,说明他最近看到一些关于 JS 垃圾回收机制的相关的文章,为了 B 格 ...

  6. 阿里巴巴Web前端面试的一道JS题目,求解答!!!

    题目大概是这种: function outer(){ return inner; var inner = "a"; function inner(){}; inner = 9; } ...

  7. web前端面试官挖的那些坑(js)

    题目1: function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () ...

  8. 前端面试:Vue.js常见的问题

    摘自今日头条用户:代码开发 原文链接: https://www.toutiao.com/a6683120112255369732/?tt_from=mobile_qq&utm_campaign ...

  9. web前端面试系列 一 js闭包

    一.什么是闭包? JavaScript高级程序设计第三版: 闭包是指有权访问另一个函数作用域中的变量的函数. 在js中定义在函数内部的子函数能够访问外部函数定义的变量,因此js内部函数就是一个闭包. ...

随机推荐

  1. Ubuntu18.04.3 LTS初体验

    安装系统 想来虚拟机安装太慢,正好有一台旧电脑,干脆整个乌班图系统. 启动盘工具:UltraISO,老牌工具了. 上官网下载ISO镜像文件: https://cn.ubuntu.com/downloa ...

  2. Win32 COM组件 x Android Service

    有些书在介绍和讲解android的Service组件时,会使用后台服务一词,并且与运行在主线程的Activity相对.因为后台一词很容易误解,服务一直运行在后台?什么线程在运行?服务一直有条线程在运行 ...

  3. Win10专业版和企业版的区别

    微软最新的Windows 10版本诸多,包括精简版(S).家庭版(Home).专业版(Pro).企业版(Enterprise),而论功能体验,Win10专业版和企业版无疑是最完善的.那么,Win10专 ...

  4. php设置随机ip访问

    当我们请求一个站点的时候,http报文头会携带一些ip信息,我们通过伪造这些信息,就可以形成不同ip访问请求的效果. header的头部CLIENT-IP和X-FORWARDED-FOR我们都设置为想 ...

  5. 【2018寒假集训 Day2】【动态规划】钱币兑换(exchange)(自己翻译的2333)

    钱币兑换(exchange) 问题描述: Dave偶然获得了未来几天的美元(dollars)与马克(marks)之间的兑换率.例如Dave开始有100marks,请编写个程序帮助Dave找出最好的买卖 ...

  6. python字符串、正则-xdd

    1.分割字符串 str.split(sep,maxsplit) #(分隔符,分几次) 2.合并字符串 str2=string.join(iterable) #str2='@'.join(list1) ...

  7. C#面向对象--命名空间

    一.在C#中,使用命名空间(Namespace)可以帮助控制自定义类型的作用范围,同时对大量的类型进行组织:使用namespace关键字声明命名空间,命名空间可以嵌套使用: namespace MyN ...

  8. ES6之Set

    阮大神的es6看了一遍,但是对于Set和Map还是一知半解的,主要还是没怎么用吧,这里总结一下,以后再工作中也要多用用才行 怎么定义set呢?有什么用处? set是ES6中新增的类型,和数组类似,唯一 ...

  9. LinkedList实现原理(JDK1.8)

    LinkedList实现原理(JDK1.8) LinkedList底层采用双向链表,如果对链表这种结构比较熟悉的话,那LinkedList的实现原理看明白就相当容易. 链表通过"指针&quo ...

  10. 通过Python将Excel表格信息导入数据库

    前言 公司原采用Excel表格方式记录着服务器资产信息,随着业务的增加,相应的硬件资产也增加,同时物理机虚拟化出多台虚拟机,存在表格管理杂乱.变更资产信息不能及时相互同步, 为了紧跟时代的步伐,老大搞 ...