0
点赞
收藏
分享

微信扫一扫

JS高级-面向对象特征,原型链 原型链应用 函数补充

你的益达233 2022-04-30 阅读 69

面向对象特征

面向对象三大特征

封装 继承 多态

封装

继承

多态 

原型继承 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
        1.继承 :  一个对象 拥有 另一个对象 所有的 成员
        2.原型继承 :把父对象 作为子对象构造函数的原型
        */
    //    父对象
let father={
    house:{
  address:'汤臣一品',
price:20000000  
    },
    car:{
        brand:'劳斯莱斯幻影',
        price:15555
    }
}
// 构造函数
     function Son(name,age){
  this.name=name
  this.age=age
     }  
    //  原型继承,把父对象作为子对象构造函数的原型
     Son.prototype=father
    //  实例对象
     let s1=new Son('张三',18)
     let s2=new Son('李四',20)
     console.log(s1,s2);
        //可选 : 原型继承之后,由于父对象覆盖原来的 子对象构造函数原型, 就会导致constructor消失.
        //解决办法: 手动添加。(对开发几乎没有影响,也可以不加)    
    </script>
</body>
</html>

原型链 

01 原型链

 

 <script>
       /* 
       1.原型链 : 每一个对象都有自己的原型, 而原型也是对象,也会有自己的原型,此次类推形成链式结构。称之为原型链。(原型链的终点是null)
       2.对象访问原型链规则 : 就近原则
        * 对象先访问自己的,自己没有就找原型的,原型没有就找原型的原型,一直到原型链终点null.如果还找不到。  属性则获取undefined, 方法则会报错 xxx is not function
       */     
// 构造函数
function Person(name,age){
    this.name=name
    this.age=age
}
// 原型对象
Person.prototype.eat=function(){
    console.log('吃东西');
}       
Person.prototype.type='哺乳动物'       
// 实例对象
let p1=new Person('张三',18)
       
// 查看p1的原型对象       

console.log(p1.__porto_.constructor); //Person
console.log(p1.__porto_===Person.prototype);
    //  查看p1的原型对象的原型
    console.log(p1.__porto_.__porto_.constructor);//Object
    console.log(p1.__porto_.__porto_===Object.prototype);  //true
    </script>

 02 内置对象原型链

内置对象原型链

 <script>
        /*
        1.原型链 : 每一个对象都有自己的原型, 而原型也是对象,也会有自己的原型,此次类推形成链式结构。称之为原型链。(原型链的终点是null)
       2.对象访问原型链规则 : 就近原则
       3.原型链作用 继承
        js用什么技术实现面向对象的继承 :原型链*/
        
        // 数组对象  
        //实例化对象
        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
        
    </script>

03-instanceof运算符

<script>
        /* 
        1. instanceof(关键字): 运算符。 用于检测 构造函数的prototype在不在实例对象的原型链中
          说人话: 亲子鉴定,鉴定两个对象之间有没有血缘关系
        面试点 检测右边构造函数的原型在不在左边实例对象原型链中
          2.  实例对象 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 reverseStr(arr){
            // 
            if(arr instanceof  Array){
            arr.reverse()
            console.log(arr.join(''));
            
            }else{
                console.log('数据类型');
            }
        }
                reverseStr('你','是')


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

    </script>

 03原型链应用-封装提示框

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>面向对象封装消息提示</title>
    <style>
      .modal {
        width: 300px;
        min-height: 100px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
        border-radius: 4px;
        position: fixed;
        z-index: 999;
        left: 50%;
        top: 50%;
        transform: translate3d(-50%, -50%, 0);
        background-color: #fff;
      }
      .modal .header {
        line-height: 40px;
        padding: 0 10px;
        position: relative;
        font-size: 20px;
      }
      .modal .header i {
        font-style: normal;
        color: #999;
        position: absolute;
        right: 15px;
        top: -2px;
        cursor: pointer;
      }
      .modal .body {
        text-align: center;
        padding: 10px;
      }
      .modal .footer {
        display: flex;
        justify-content: flex-end;
        padding: 10px;
      }
      .modal .footer a {
        padding: 3px 8px;
        background: #ccc;
        text-decoration: none;
        color: #fff;
        border-radius: 2px;
        margin-right: 10px;
        font-size: 14px;
      }
      .modal .footer a.submit {
        background-color: #369;
      }
    </style>
  </head>
  <body>
    <button id="btn1">消息提示1</button>
    <button id="btn2">消息提示2</button>
    <button id="btn3">消息提示3</button>


    <!-- <div class="modal">
      <div class="header">提示消息 <i>x</i></div>
      <div class="footer">
        <img src="./111.jpg" alt="" width="80%">
      </div>
    </div> -->
    

    <script>
      // 1.构造函数     里面的每一个模态框不同的数据
function Modal(title,url){
this.title=title
this.url=url
this.box=`

<div class="modal">
      <div class="header">${this.title} <i>x</i></div>
      <div class="footer">
        <img src="${this.url}" alt="" width="80%">
      </div>
    </div> 
`
}
    // 原型    灭一个模态框共有的方法
    Modal.prototype.show=function(){
      // (1)创建空标签
      let div=document.createElement('div')
      // (2)设置标签内容
      div.innerHTML=this.box
      // 谁调用这个函数,this就指向谁
      // (3)添加到页面
    document.body.appendChild(div)
    div.querySelector('i').onclick=function(){
      div.remove()
    }
    }



      /* 点击按钮 */

      //按钮1
      document.querySelector('#btn1').onclick = function(){
      // 实例对象
      let m1=new Modal('提示文字','./111.jpg')
      m1.show()
      }

      //按钮2
      document.querySelector('#btn2').onclick = function(){
        let m2=new Modal('提示文字','./222.jpg')
      m2.show()
      
      }

      //按钮3
      document.querySelector('#btn3').onclick = function(){
        let m3=new Modal('友情提示','./333.jpg')
      m3.show()
        
      }

      
    </script>
  </body>
</html>

 

 04函数补充

01-arguments关键字

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

        2. 应用 : 一般用于参数数量不限的函数. 
            例如: arr.push()  Math.max()  这些方法可以传很多个参数,在函数内部就需要arguments来获取所有的实参
        */

      function fn(a, b) {
        console.log(a);  //undefined
        console.log(b); //undefined
        console.log(a + b);  //NaN
        console.log(arguments);
      }

      fn();  
      fn(10);
      fn(10, 20);
      fn(10, 20, 30);
      fn(10, 20, 30, 40);
     
    </script>

 02-剩余参数rest

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

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

        3. 剩余参数(rest参数) : 获取函数剩余的所有实参
            语法:  function 函数名(形参1,...形参2){}
            特点: (1)只能作为最后一个参数  (2)是真数组

        4. 剩余参数,rest参数可以替代arguments
        */    

        function fn(...b){
            console.log(b)//10
            console.log(arguments)
            
        }

        fn(10)
        fn(10,20)
        fn(10,20,30)
        fn(10,20,30,40)


        
    </script>

 03函数默认参数

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

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

        3. 剩余参数(rest参数) : 获取函数剩余的所有实参
            语法:  function 函数名(形参1,...形参2){}
            特点: (1)只能作为最后一个参数  (2)是真数组

        4. 一般情况下,rest参数可以替代arguments

        5. 函数默认参数
            function 函数名(形参=默认值){  }
        */    

        function fn(a=0,b=0){
            //fn(a,b)  10+undefined=NUN
            //以前: 逻辑或短路
            // 找真 : 左边是真就返回左边式子的值,否则返回右边式子的值
            // a = a || 1
            // b = b || 2
            console.log( a + b ) 
        }

        fn(10)
        fn(5,0)

        
    </script>

 04js变量作用域

 

  <script>
    /* 
    
   1 变量作用域:变量可以使用的范围
    2.三种作用域
    全局作用域:变量可以在页面任何地方使用
      全局变量:在大括号外面声明
    局部作用域:变量只能在函数内部
      局部变量:在函数内声明的变量
    块级作用域:变量只能在大括号(分支+循环)内部使用
            块级变量:在大括号内部声明的变量   */ 
function f1(){
  let num=5
}
function f2(){
  let num=5
}
    
  </script>

 05作用域链

  <script>
 /* 1 变量作用域:变量可以使用的范围
    2.三种作用域
    全局作用域:变量可以在页面任何地方使用
      全局变量:在大括号外面声明
    局部作用域:变量只能在函数内部
      局部变量:在函数内声明的变量
    块级作用域:变量只能在大括号(分支+循环)内部使用
            块级变量:在大括号内部声明的变量    
    3.作用域链
    默认情况下 代码是全局作用域(0级),声明函数之后就会变成局部作用域(1级),函数内部又可以声明函数,有会形成局部作用域(2级),以此类推
    4.变量访问作用域链规则:就近原则
      先在当前作用域找声明,有声明就用自己的,自己没有就找上级声明,有酒访问,没有就继续找上级找到最顶级(0级)还是未找到就 报错 xxx is not defined

*/
// 0级
let num=10
function fn(){
  // 1级
  // let num =20
  console.log(num);//10
  function fn1(){
    // 2级
    let num =30
    // console.log(num);//30
  }
  fn1()
}
fn()
// console.log(num);//10
  </script>

 06let 与const 的区别

07 for in与 for of 的区别

y>
    <script>
        /* for-in与for-of区别 
        1.功能不同
            for-in是遍历数组的下标和元素
            for-of是遍历数组的元素
        2.原型的属性
            for-in会遍历原型的属性
            for-of不会遍历原型的属性
        3.数据类型不同
            for-in会遍历数组和对象
            for-of只能遍历数组
        
    总结:如果想要遍历数组的下标和元素就用for in,如果想遍历数组的元素就用for of
        */

        //数组
        let arr = ['a','b','c']//下标0 1 2
        //给原型添加成员
        Array.prototype.age = 30

        //对象
        let obj = {name:'ikun',age:30}
        

        //遍历数组
        //for-in
        for(let key in arr){
            console.log(key,arr[key])//下标,元素
        }
        //for-of
        for (let item of arr ) {
            console.log(item)  //元素     
        }

        //遍历对象 : 程序报错
        // for (let item of obj ) {
        //     console.log(item)  //属性名    
        // }
   
    </script>

 

举报

相关推荐

0 条评论