• 攻略前端面试官(三):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

  • 相关阅读:
    如何把SQLServer数据库从高版本降级到低版本
    关于如何利用Pocket CHM Pro制作帮助文档
    关于ASP.net TextBox控件的失去焦点后触发其它事件
    由window.history.back()引发的问题
    设置按钮不可用避免重复提交
    【转】一个高端.NET技术人才的2014年度总结
    Zabbix 各种报错信息和遇到的问题处理(持续总结更新~~~~~)
    ASP.NET调用Web Service
    ASP.NET导出bdf文件
    CS文件密码加密类
  • 原文地址:https://www.cnblogs.com/shizheng0909/p/12052524.html
Copyright © 2020-2023  润新知