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>