zoukankan      html  css  js  c++  java
  • 原型和原型链

    一般会问的问题:

    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的原型本质,怎么理解?

    答案:

    • 上面原型和原型链的图示
    • 属性和方法的执行规则
  • 相关阅读:
    Vue中事件委托的使用
    java提取每个汉字的首字母
    想把大脑存进电脑,我为什么要写博客
    CF 1606 D题题解
    js前端 音频波形图像展示
    js前端 仪表盘实现
    js前端 bootstrap select的使用
    UOS系统维护命令
    linux 打印机管理常用命令
    linux 调用shell命令
  • 原文地址:https://www.cnblogs.com/queenya/p/13659441.html
Copyright © 2011-2022 走看看