原型和原型链

一般会问的问题:

  1. 创建对象有几种方法
  2. 原型、构造函数、实例、原型链
  3. instanceof 的原理
  4. new 运算符

创建对象有几种方法

原型关系

  • 每个class(class 实际是函数,是语法糖)都有显示原型 prototype
  • 每个实例都有隐式原型 __proto__
  • 实例的 __proto__ 指向对应class 的 prototype

基于原型的执行规则

  • 获取属性 xialuo.name 或执行方法 xialuo.sayhi() 时
  • 先在自身属性和方法寻找
  • 如果找不到则自动去 __proto__ 中寻找

原型、构造函数、实例、原型链

  • 原型链:从一个实例对象往上找构造这个实例的相关联的对象,然后这个关联的对象再往上找它又有创造它的上一级的原型对象,以此类推,一直到 Object.prototype 原型对象终止,这个链条就断了,也就是说 Object.prototype 是整个原型链的顶端。通过什么往上找?就是通过 prototype 和 __proto__.
  • 原型:构造函数都有一个 prototype 属性,这是在声明一个函数时js 自动增加的,这个 prototype 指的就是原型对象。原型对象怎么区分被哪个构造函数引用?就是通过 constructor(构造器),原型对象中会有一个构造器,这个构造器会默认声明的那个函数。
  • 构造函数:任何一个函数只要被 new 去操作(使用)就是构造函数,构造函数也是函数
  • 实例:只要是对象就是一个实例
  • 构造函数可以使用new 生成实例

通过原型链的方式找到原型对象,原型对象的方法是被不同的实例所共有的,这就是原型链的一个工作原理
1、构造函数(函数)才有propotype 的,对象没有 propotype,
2、只有实例对象有 __proto__的,函数既是函数又是对象

 原型链

  • 如果实例中有自身属性则直接使用自身的属性(如图中 xialuo),如果没有则会再自身的隐式原型链中去找,一直找到最顶级 Object 为止,如果都找不到,则最后返回的null
  • 每个构造函数都有一个显示原型prototype (如 Student, People),且每个显示原型都会对应有一个隐式原型__proto__,而他的隐式原型的父级又有个显示原型,他们都是一级级往上找的,然后一直找到树形结构的第一层(Object)为终点
  • instanceof 是为判断此实例或构造函数是否是父级继承的,如(xialuo instanceof People  // true, xialuo instanceof Array  // false)

instanceof 原理:
实例对象的 __proto__ 和构造函数本身没有什么关联,它关联的是构造函数 prototype 下面的一个属性即 prototype 所引用的原型对象

是判断 实例对象.__proto__ 和 构造函数.prototype是不是一个引用(即引用同一个地址)

 

new 运算符

new 构造函数的原理:

生成一个空对象(Object.create)

将空对象的__proto__指向构造函数的prototype  var o = Object.create(func.prototype)

执行构造函数,this 上下文指向空对象  var k = func.call(o)

若构造函数返回的是对象,那么这个对象将取代原来的空对象

if(typeof k === 'object') {

return k

} else {

return o

}

题目

如何准确判断一个变量是不是数组?

答案:用 instanceof, 如 a instanceof Array

手写一个简易的 jQuery,考虑插件和扩展性

 1 class jQuery {
 2     constructor(selector) {
 3         const result = document.querySelectorAll(selector)
 4         const length = result.length
 5         for(let i = 0; i < length; i++) {
 6             this[i] = result[i]
 7         }
 8         this.length = length
 9         this.selector = selector
10     }
11     get(index) {
12         return this[index]
13     }
14     each(fn) {
15         for(let i = 0; i < this.length; i++) {
16             const elem = this[i]
17             fn(elem)
18         }
19     }
20     
21     on(type, fn) {
22         return this.each(elem => {
23             elem.addEventlistener(type, fn, false)
24         })
25     }
26 }
27 
28 jQuery.propotype.dialog = function(info) {
29     alert(info)
30 }
31 
32 class myJQuery extends jQuery {
33     constructor(selector) {
34         supper(selector)
35     }
36     addClass(className) {
37     }
38     style(data) {
39     }
40 }

class的原型本质,怎么理解?

答案:

  • 上面原型和原型链的图示
  • 属性和方法的执行规则
原文地址:https://www.cnblogs.com/queenya/p/13659441.html