JS基础(一)-变量到原型详解

变量类型 基本数据类型 Boolean String Number undefined 复杂数据类型 Object Null Function

typeof 运算符 能够识别的类型 只有基本数据类型 和Object Function 这里function类型也是引用类型 函数在JS中是一等公民 

自动类型转换 

(1)如果一个操作值为布尔值,则在比较之前先将其转换为数值
(2)如果一个操作值为字符串,另一个操作值为数值,则通过Number()函数将字符串转换为数值
(3)如果一个操作值是对象,另一个不是,则调用对象的valueOf()方法,得到的结果按照前面的规则进行比较
(4)null与undefined是相等的
(5)如果一个操作值为NaN,则相等比较返回false
(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象

======简述构造函数 原型 原型链

    <script>
        function Foo (name){
            this.name = name
        }
        Foo.prototype.printName = function(){
            console.log(this.name)
        }
        const f = new Foo('Tom')
        console.log(f.__proto__ === Foo.prototype)
        f.printName()
    </script>

每个构造函数都有一个原型 而构造函数所实例的对象 都有一个__proto__属性 指向构造函数的原型 实例所指向的原型对象(隐式原型) 与 构造函数指向的原型(显示原型) 是完全相等的

原型就是所有实例共享的对象 而原型对象的__proto__又指向了Object构造函数的prototype Object.prototype 最终指向了null 每个构造函数的实例所遵循的原型链查找机制 是自下而上的

同时函数也可以理解为一个对象 是的构造函数Function实例 而funciont (){} 的写法就是new Funcion()的变形 那么Funcion同样也有prototype原型对象指向了 Function.prototype对象 -> Object.prototype ->null 而每个构造函数都有一个name属性指向了函数名

同样原型对象中的constructor也指向了构造函数的name 这里function也是对象也有隐式原型 在function的隐式原型中 构造函数指向了Function 下面一张原型链的简图 可以自己画一下

在for in 遍历对象中实际上是需要 屏蔽掉原型中的属性的

    <script>
    const obj = {
        name:'tom'
    }
        for(let key in obj){
            if(obj.hasOwnProperty(key)){
                console.log(obj[key])
            }
        }
    </script>

同样前面说过typeof不能判断具体对象类型除了函数那么如何判断数组呢 这里可以使用 [] instanceof  Array 这里的意思是 按照 [].__proto__ 的原型链进行查找看看在这条原型链上 有没有 Array.prototype 如果有返回true

console.log([] instanceof Array) 

 接下来在实际中原型对象的运用场景 这里用jQuery框架的设计模式作为实例 第一个演示例子

    <div id="box"></div>
    <script>
        function Elem(id){
            this.ele = document.getElementById(id)
        }
        

        Elem.prototype.html = function(val){
            if(val){
                this.ele.innerHTML = val
                return this
            }
            return this.ele.innerHTML
        }
        Elem.prototype.on = function(type,fn){
            this.ele.addEventListener(type, fn)
        }

    const obj = new Elem('box')
    obj.html('111').on('click',function(){
        console.log(222)
    })
    </script>

上面代码使用构造函数与原型可以轻易实现链式操作 下面简述一下jQuery的实现原理 有机会详细解读一下

同样jq也有一个DOM选择器模块 它这个模块非常强大 jq除了工具类函数 其他都是基于这个选择器模块的

    <div id="box"></div>
    <script>
        (function(){
            //首先jq释放一个接口给用户
            const $ = function(select){
                //返回构造函数的实例对象
                return new $.fn.init(select)
            }
            //改变原型
            $.fn = $.prototype = {
                //创建构造函数
                init:function(select){
                    this.ele = document.getElementById(select)
                },
                //下面就是jq的代码了

                sayHi:function(){
                    console.log(222)
                }
            }
            $.fn.init.prototype = $.fn
            window.$ = $

        })()

        //为什么不直接定义一个构造函数返回实例 这是jq帮我们省略了自己new的一个过程给我们封装了一个接口 同时我们在链式操作的时候想要改变dom 可以使用$('').init('') 这样更加方便
        $('box').sayHi()

        
    </script>
原文地址:https://www.cnblogs.com/tengx/p/9008236.html