JavaScript 原形链

1.面向对象:是一种注重结果的思维方式

2.面向对象三大特征: 封装 、 继承 、 多态

(1).封装 : 把代码放入对象的方法中

(2)继承 : 一个对象 拥有 另一个对象 所有的成员

(3)多态 : 一个对象 在不同情况下的不同状态(* js语言基本不涉及多态)

继承:一个对象 拥有另一个对象的所有成员

原形继承:吧父对象 作为子对象构造函数的原形

例子:

//父对象
        let father = {
            house:{
                address : '深圳湾一号',
                price: 20000000
            },
            car:{
                brand : '劳斯莱斯幻影',
                price:15000000
            }
        }

        //子对象
        //构造函数
        function Son(name,age){
            this.name = name
            this.age = age
        }
        //原型继承: 把父对象 作为子对象构造函数的原型
        Son.prototype = father
        //可选 : 原型继承之后,由于父对象覆盖原来的 子对象构造函数原型, 就会导致constructor消失.
        //解决办法: 手动添加。(对开发几乎没有影响,也可以不加)
        Son.prototype.constructor = Son

        //实例对象
        let s1 = new Son('ikun',30)
        let s2 = new Son('班长',20)
        console.log(s1,s2)

原形链:

1.原型链 : 每一个对象都有自己的原型, 而原型也是对象,也会有自己的原型,此次类推形成链式结构。称之为原型链。(原型链的终点是null)

2.对象访问原型链规则 : 就近原则

* 对象先访问自己的,自己没有就找原型的,原型没有就找原型的原型,一直到原型链终点null.如果还找不到。 属性则获取undefined, 方法则会报错 xxx is not function

3.经典面试题

(1)原形链作用 : 继承

(2)js如何实现面向对象继承:原形链

原形链流程图

所有构造函数都是Function的实例,所有原型对象都是Object的实例除了Object.prototype

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5qKm6L-q4oCUMA==,size_20,color_FFFFFF,t_70,g_se,x_16

内置对象原型链

 // 数组对象  
        //实例化对象
        let arr = [10,20,30]//new Array(10,20,30)
        console.log( arr )
        //1.1 查看arr的原型
        console.log( arr.__proto__.constructor )//Array
        console.log( arr.__proto__ === Array.prototype )//true
        //1.2 查看arr的原型的原型
        console.log( arr.__proto__.__proto__.constructor )//Object
        console.log( arr.__proto__.__proto__ === Object.prototype )//true
        
        // 字符串对象
        let str = new String('abc')
        console.log( str )
        //2.1 查看str的原型
        console.log( str.__proto__.constructor )//String
        console.log( str.__proto__ === String.prototype )//true
        //2.2 查看arr的原型的原型
        console.log( str.__proto__.__proto__.constructor )//Object
        console.log( str.__proto__.__proto__ === Object.prototype )//true
        
        // 日期对象
        let date = new Date()
        /* js有几个特殊的对象 无法使用 log来打印的,需要用dir来打印: function date dom对象 */
        console.dir( date )
        //3.1 查看date的原型
        console.log( date.__proto__.constructor )//Date
        console.log( date.__proto__ === Date.prototype )//true
        //3.2 查看date的原型的原型
        console.log( date.__proto__.__proto__.constructor )//Object
        console.log( date.__proto__.__proto__ === Object.prototype )//true

DOM对象原型链

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5qKm6L-q4oCUMA==,size_20,color_FFFFFF,t_70,g_se,x_161. instanceof(关键字): 运算符 

用于检测 构造函数的prototype在不在实例对象的原型链中(说人话: 亲子鉴定,鉴定两个对象之间有没有血缘关系)

2. 写法:实例对象 instanceof 构造函数

instanceof原理: (面试题)

检测 右边构造函数的prototype 在不在 左边实例对象的原型链中

3. 应用 : 某些函数为了限制你的数据类型,在内部需要用instanceof进行判断是否是正确的数据类型

例子:

let arr = [10,20,30]
        // arr-> Array.prototype -> Object.prototype -> null
        console.log( arr instanceof Array )//true
        console.log( arr instanceof Object )//true
        console.log( arr instanceof String )//false

        //封装一个函数,要求这个函数必须要传数组类型、 传其他类型不可以
        function fn(arr){
            if( arr instanceof Array){
                console.log( arr.reverse() )
            }else{
                console.log('数据类型错误')
            }
        }

        fn( [10,20,30] )
        fn( 'abc' )

原型链应用:封装提示框案例

  <script>
    // 构造函数
    function Modal(title, url) {
      this.title = title
      this.url = url
      this.modalBox = `
      <div class="modal">
      <div class="header">${title} <i>x</i></div>
      <div class="footer">
      <img src="${url}" alt="" width="100%">
      </div>
      </div>
      `
    }

    // 对象
    Modal.prototype.open=function(){
      // 创建div
      let div = document.createElement('div')
      // 设置标签内容
      div.innerHTML = this.modalBox
      // 添加到页面
      document.body.appendChild(div)
      // 给关闭按钮注册事件
      div.querySelector('.modal i').addEventListener('click',function(){
        div.remove()
      })

    }

    // 实例对象
   document.querySelector('#btn1').addEventListener('click',function(){
    let m1 = new Modal('提示信息', './111.jpg')
    m1.open()
    console.log(m1)
   })

   document.querySelector('#btn2').addEventListener('click',function(){
    let m2 = new Modal('提示信息', './222.jpg')
    m2.open()
    
   })

   document.querySelector('#btn3').addEventListener('click',function(){
    let m3 = new Modal('提示信息', './333.jpg')
    m3.open()
    
   })
  </script>

函数补充

1: arguments关键字: 获取函数所有的 实参,是一个伪数组 : 有数组三要素(元素、下标、长度),但是不能使用数组的方法。

(1)应用 : 一般用户参数数量不限的函数.

 (2)例如: arr.push() Math.max() 这些函数实参数量不限,底层原理就是使用arguments来接收所有的实参

2: 剩余参数(rest参数) :  获取函数剩余的所有实参

(1)语法: function 函数名(形参1,...形参2){}

  (2) rest参数是真数组

(3)注意点:剩余参数必须写在最后一个形参位置

3:rest参数在一般情况下,可以替代arguments

4: 函数默认参数:function 函数名(形参=默认值){ }

例子:

       function fn(a=10,b=20){ //实参有数据则是实惨的数据 实参没有数据则是=后面的数据
            console.log(a) //5
            console.log(b) //20
            console.log(a+b) //25
        }
         fn(5)

for-in与for-of区别(面试题)

1.功能不同

for-in是遍历数组的下标

for-of是遍历数组的元素

2.原型的属性

for-in会遍历原型的属性

for-of不会遍历原型的属性

3.数据类型

for-in可以遍历Object类型

for-of不可以遍历Object类型

总结:如果只想要属性值/元素,使用for-of效率更高

例子:

        let arr = [10,20,30]
        console.log(arr)
        //给数组原型添加属性
        Array.prototype.age = 66
        
        let obj = {
            name:'张三',
            age:20,
            sex:'男'
        }

        //1.for-in循环
        for(let key in arr){
            console.log( key )//下标
            console.log( arr[key] )//元素  
        }

        //2. for-of循环
        for(let item of obj ){
            console.log( item )//元素 
        }

变量声明let与var

1. ES5声明变量特点: var

(1)有变量提升 : var声明提升到当前作用域最顶端

(2)没有块级作用域 : 大括号(分支+循环)里面的变量是全局的

2. ES6声明变量特点: let const

(1) 没有变量提升 : 变量必须要先声明,后使用

(2) 有块级作用域 : 大括号(分支+循环)里面的变量是局部的

3. let与const区别 :

let 变量 : 值可以修改的

const 常量 : 值不可以修改, 只能在声明的时候赋值

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值