攻略前端面试官(三):JS的原型和原型链


关于构造函数和原型

构造函数:相当于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究竟是什么关系,这个问题一度困扰着我,直到我看到了这张图

F&O

简单理解为:

  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等。

引用https://www.cnblogs.com/rainykane/p/12047477.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM