zoukankan      html  css  js  c++  java
  • JS原型及原型链

    1、构造函数、原型对象、实例化原型对象三者的关系:

     2、构造函数new的几个过程

    - 创建一个新对象
    - `this`指向这个新对象
    - 执行代码,即对`this`赋值
    - 返回`this`

    function Foo(name) {
        this.name = name
        this.type = 'foo'
    }
    var foo = new Foo('beijing')
    

    3、构造函数 - 扩展

    - `var a = {}`其实是`var a = new Object()`的语法糖
    - `var a = []`其实是`var a = new Array()`的语法糖
    - `function Foo(){...}`其实是`var Foo = new Function(...)`的语法糖

    4、原型链的5个要点

    1. 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了`null`意外)
    2. 所有的引用类型(数组、对象、函数),都有一个`__proto__`属性,属性值是一个普通的对象
    3. 所有的函数,都有一个`prototype`属性,属性值也是一个普通的对象
    4. 所有的引用类型(数组、对象、函数),`__proto__`属性值指向它的构造函数的`prototype`属性值
    5. 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的`__proto__`(即它的构造函数的`prototype`)中寻找
    var obj = {}; obj.a = 100;
    var arr = []; arr.a = 100;
    function fn () {}
    fn.a = 100;
    
    console.log(obj.__proto__);
    console.log(arr.__proto__);
    console.log(fn.__proto__);
    
    console.log(fn.prototype)
    
    console.log(obj.__proto__ === Object.prototype)

    5、prototype继承

    所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:

    • Date 对象从 Date.prototype 继承。
    • Array 对象从 Array.prototype 继承。
    • Person 对象从 Person.prototype 继承。

    所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

    JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

    Date 对象, Array 对象, 以及 Person 对象从 Object.prototype 继承。

    6、原型链实例

    // 动物
    function Animal() {
        this.eat = function () {
            console.log('animal eat')
        }
    }
    //
    function Dog() {
        this.bark = function () {
            console.log('dog bark')
        }
    }
    Dog.prototype = new Animal()
    // 哈士奇
    var hashiqi = new Dog()
    // 构造函数
    function DomElement(selector) {
        var result = document.querySelectorAll(selector)
        var length = result.length
        var i
        for (i = 0; i < length; i++) {
            this[i] = selectorResult[i]
        }
        this.length = length
    }
    // 修改原型
    DomElement.prototype = {
        constructor: DomElement,
        get: function (index) {
            return this[index]
        },
        forEach: function (fn) {
            var i
            for (i = 0; i < this.length; i++) {
                const elem = this[i]
                const result = fn.call(elem, elem, i)
                if (result === false) {
                    break
                }
            }
            return this     指向当前触发时间的对象,可以无限触发,多次调用
        },
        on: function (type, fn) {
            return this.forEach(elem => {
                elem.addEventListener(type, fn, false)
            })
        }
    }
    
    // 使用
    var $div = new DomElement('div')
    $div.on('click', function() {
        console.log('click')
    })

    7、伪数组、类数组

    实际应用中,和数组同样重要、起同样作用并且更加灵活的数据结构还是“伪数组”或者“类数据”(jquery 就用到了)。因此,在实际应用中,只需要判断`length`属性是否是数字即可。

    var arr = []
    var likeArr = {
        0: 'aaa',
        1: 'bbb',
        2: 'ccc',
        length: 3
    }
    
    typeof arr.length === 'number' // true
    typeof likeArr.length === 'number' // true
    

     8、如何准确判断一个变量是数组类型

    typeof仅能判断 值类型,引用类型中,仅能判断 function和object

    判断数组的话,需要用instanceof

    instanceof原理:(基于的是原型链)

    如果要计算`f instanceof Foo`是不是正确,就要判断`f`的原型一层一层往上,能否对应到`Foo.prototype`。同理,如果要计算`f instanceof Object`是不是正确,就要判断`f`的原型一层一层往上,能否对应到`Object.prototype`

    // 构造函数
    function Foo(name, age) {
        this.name = name
    }
    Foo.prototype.alertName = function () {
        alert(this.name)
    }
    // 创建示例
    var f = new Foo('zhangsan')
    f.printName = function () {
        console.log(this.name)
    }
    // 测试
    f.printName()
    f.alertName()

    9、原型链示意图

    10、如何判断一个这个属性是不是对象本身的属性

    使用`hasOwnProperty`(屏蔽了来自原型的属性),常用的地方是遍历一个对象的时候

    var item
    for (item in f) {
        // 高级浏览器已经在 for in 中屏蔽了来自原型的属性,但是这里建议还是加上这个判断,保证程序的健壮性
        if (f.hasOwnProperty(item)) {
            console.log(item)
        }
    }
    

     11、原型链中的`this`

    所有的从原型或者更高级的原型中得到、执行的方法,其中的`this`在执行时,就指向了当前这个触发事件执行的对象。

     

  • 相关阅读:
    jdk环境变量配置
    智商太低,竟然算不出病狗神题了
    HDU 1284 钱币兑换问题 母函数、DP
    linux下实现监控进程网络带宽
    编程算法
    C語言 rand函数 进阶探讨与实现
    JDBCUtil
    iOS进阶路线以及进阶书籍
    Windows平台CUDA开发之前的准备工作
    数据库中substring的用法 CONVERT(varchar(12) , getdate(), 112 )
  • 原文地址:https://www.cnblogs.com/shary-blue/p/14027418.html
Copyright © 2011-2022 走看看