js 高级06

1.理解函数也是对象

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>
<script>
  /*   
    函数也是对象
    万事万物是对象---猜测函数也是对象

     1.函数也可以点出方法
     2.函数也可以点出属性
     3.函数都是实例对象
 */

  console.log(Object.prototype);
  console.log(Object.__proto__);

  function fn() {}
  fn.call()

  // 所有的函数都是Function的实例对象
  console.log(Object instanceof Function);
  console.log(Array instanceof Function);

  console.log(Array.prototype.push instanceof Function);
  console.log(alert instanceof Function);

  // 以上结果都为true

</script>

</html>

 

2.研究function

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
   
  //  Function 也是个函数
  //  作用:用来创建函数的
  //  用法:var fn=new Function(参数1,参数2,参数3...,函数体)

  //  函数其实都是由 Function创造出来的实例对象

  //  console.log(Function);
  //  console.dir(Function);



  //  正常写函数
  //  function fn(a,b){
  //    return a+b;
  //  }

  //  console.log(fn(10,20));


   var fn=new Function('a','b','return a+b')
   console.log(fn(10,20));
   console.log(fn);
   console.dir(fn)

  //  每个函数都有两个原型  并且为同一个
  //  prototype 如果一个函数作为构造函数使用,相当于他老公
  //  __proto__ 如果一个函数看做是一个实例对象 相当于是他爹


  </script>
</html>

 

3.研究function家族原型链

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
   
  //  Function 原型
  //    Function.prototype

   console.dir(Function)
   console.dir(Function.prototype.__proto__)
   console.log(Function.prototype.__proto__===Object.prototype)


console.log(Function.prototype instanceof Object);
console.log(Function.prototype.__proto__.constructor===Object);


console.log(Function.prototype.__proto__.__proto__);
consol.dir(Object.prototype)


// 证明任意一个函数都可以调用Object原型上的方法

function fn(){}
  console.dir(fn)
  console.log(fn.hasOwnProperty('name'));

  </script>
</html

 

4.原型链的全图

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
   
  //  Function 原型
  //    Function.prototype

   console.dir(Function)
   console.dir(Function.prototype.__proto__)
   console.log(Function.prototype.__proto__===Object.prototype)


console.log(Function.prototype instanceof Object);
console.log(Function.prototype.__proto__.constructor===Object);


console.log(Function.prototype.__proto__.__proto__);
consol.dir(Object.prototype)


// 证明任意一个函数都可以调用Object原型上的方法

function fn(){}
  console.dir(fn)
  console.log(fn.hasOwnProperty('name'));

  </script>
</html

 

5.借用

 

    借用:

        什么是借用:把人家的方法拿过来用

        有什么目的:非继承关系的代码复用

 

    借用通常会有两个效果:

        1.修改this

        2.调用函数

    怎么借用

       call

       apply 

       bind 

6.this的指向

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="button" value="按钮" id="btn" />
  </body>
  <script>
   /* 
   函数里的this指向
      函数的使用情况
          1.普通函数(全局函数)function this是window
          2.构造函数 --this 是实例对象
          3.事件 处理程序 除了IE浏览器 指向都是事件源
            在IE浏览器中 attacheEvent  指向都是window

          4.回调函数 大多情况下都是window
          5.对象的方法- 实例对象

          谁调用了函数 this就指向谁

 */
  
  // 普通的this
  // function fn(){
  //   console.log(this);

  // }
  // fn();
  // window.fn()



  // 构造函数的this
//   function Person(name){
//     this.name=name;
//     console.log(this);
//   }
// var p1=new Person('哈哈哈') ;



//  事件处理程序
var btn=document.getElementById('btn')
// btn.onclick=function(){
//   console.log(this);
// };

// btn.addEventListener('click',function(){
//   console.log(this);
// });



// IE中的单击事件
    // btn.attachEvent("onclick", function () {
    //   console.log(this);
    // });



// 回调函数中 this
    // setTimeout(function () {
    //   console.log(this);
    // }, 1000);

    // 对象里面的方法
    function Person(name) {
      this.name = name;
    }
    Person.prototype.say = function () {
      console.log(this);
    };
    var p = new Person("卡布达");
    // p.say();
    p.eat = function () {
      console.log(this);
      var fn = () => {
        console.log(this);
      };
      fn();
    };
    p.eat();

  </script>
</html>

 

7.call

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</body>
<script>
  /*  
    call的使用
          函数名.call(新的this,参数,参数2,参数3...)
          作用:function 
            1.修改this
            2.立刻调用函数

    */


  function fn() {
    console.log(this);
  }
  fn()


  fn.call({
    name: '李白'
  })//this 为:{name: "李白"}



  // window.Person
  function Person(name) {
    this.name = name;
  }

  // window.student
  function Student(name, age) {
    Person.call(this, name);
    console.log(this)
    this.age = age;
  }
  var s = new Student('蝎子莱莱', 10)
  console.log(s);//this为: {name: "蝎子莱莱"}



  //伪数组转成数组
  var boxs = document.getElementsByClassName("box"); //伪数组
    console.dir(boxs);
    // boxs.forEach((element) => {
    //   console.log(element);
    // });
    //es5 转换为数组
    // console.log(Array.prototype);
    // var arr = Array.prototype.slice.call(boxs, 0, boxs.length);
    // console.log(arr);

    //es6 已经准备好了将伪数组转成数组的方法
    var arr = Array.from(boxs);
    console.log(arr);
    // arr.forEach((e) => {
    //   console.log(e);
    // });

    // 原生对象类型的判断
    var date = new Date();
    var arr = new Array();
    // console.log(typeof date);
    // console.log(typeof arr);
    var type = Object.prototype.toString.call(date);

    console.log(type.substring(8).replace("]", ""));

    var type = Object.prototype.toString.call(arr);
    console.log(type.substring(8).replace("]", ""));
    // console.log(type);
    // console.log(type1);

</script>

</html>

 

8.apply

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>
<script>
  /* 
    apply 
        函数名.apply(新的this,[参数1,参数,参数3...])

        作用:
                1.立刻调用函数
                2.修改this              
     */

  function fn(a, b, c) {
    console.log(this);
    console.log(a + b + c);
  }
  fn(10, 20, 30); // this为:Window 


  fn.apply({
    name: "蜘蛛侦探"
  }, [10, 20, 30]); //this 为:{name: "蜘蛛侦探"}

  // 求数组的最大值和最小值
  var arr = [10, 80, 520, 962, 456, 782, 1654, 45];
  var aa = Math.max.apply(null, arr); //这种直接大写的构造函数点出来的方法,叫静态方法,里面不涉及this
  console.log(aa);

  //借用构造函数
  function Person(name, age) {
    this.name = name;
    this.age = age;
    console.log(this);
  }
  var s = new Person("子龙", 20);// this为:Person {name: "子龙", age: 20}
  function Student(name, age) {

    Person.apply(this, [name, age]);
    // console.log(this);
  }
  // var s = new Student("丸子龙", 20);

</script>

</html>

 

9.bind

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>
<script>
  /* 
    
    bind 作用:不会立刻执行函数 而是把函数的this修改了之后 返回一个函数的副本 通常的作用就是修改回调函数里面的this

    用法: 函数名.bind(新的this,参数1,参数2,参数3...)
    
     */
  function fn(a, b, c) {
    console.log(this);
    console.log(a + b + c);
    return 1;
  }
  var f1 = fn.bind({
    name: "呱呱蛙"
  }, 10, 20, 30);
  console.log(f1()); 


  // function fa() {
  //   return 9;
  // }
  // var a = fa();
  // console.log(a);


  setTimeout((function(){
      console.log(this);
  }).bind({name:'蟑螂恶霸'}),1000)
</script>

</html>

 

10.作用域

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: lawngreen;
        float: left;
        margin-right: 10px;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
  </body>
  <script>
    /* 
    作用域:
            1.全局作用域
                在我们页面的任何位置都可以访问到
            2.菊部作用域(局部)
                只能被函数内部访问
            3.块级作用域
                --es6才有的
                --let 关键字
    
     */
    //  全局作用域:window对象 所有的全局变量和全局函数都是window的成员 window的成员可以省略window 直接使用
    // 隐式 全局变量(不写var的变量) --不会提升的
      a = 10;
    function fn() {
      b = 20;
    }
    // console.log(a,b);
    console.log(a); //10
    // console.log(b); //报错b is not defind

    //局部作用域
    // 1.隔绝外部的影响
      function fn() {
      var a = 10;
      console.log(a);
    }
    console.log(a);
    fn()

    // 块级作用域 指的就是在一个大括号{指定的想要的语法块里}
    // let 会形成一个块级作用域
    /*   {
    let a = 10;
    }
    console.log(a); */




    // let的作用
    //     是es6推荐使用的 声明变量的关键字
    //         1.var 会提升  let不会提升 --不允许在赋值之前使用
            // 2.var 没有块级作用域  let有块级作用域
    /*  console.log(a); //undefined  此时69行只执行了定义部分 ,没有执行赋值操作
    var a = 10; 
    console.log(a);  */ //10 此时69行完成了赋值的操作

    /*  console.log(a); //报错
    let a = 10; */

    var boxs = document.getElementsByClassName("box");
    // console.log(boxs);
    /* for (var i = 0; i < boxs.length; i++) {
        boxs[i].index = i
      boxs[i].onclick = function () {
        console.log(this.index);
      };
    } */
    for (let i = 0; i < boxs.length; i++) {
      boxs[i].onclick = function () {
        console.log(i);
      };
    }
  </script>
</html>

 

 

11.作用域中访问数据的规则

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>
<script>
  /* 
        可以更加方便的管理数据
    
    作用域链的数据访问规则
        1.如果当前作用域存在这个数据,优先使用这个数据
        2.如果当前作用域没有这个数据,会沿着作用域链向外部寻找
        3.如果找到了全局都找遍了 都没有找到 会报错
    
     */
  var a = 10;

  function t1() {
    //   var a = 20;
    function t2() {
      // var a = 30;
      console.log(a);
    }
    t2();
  }
  t1();
</script>

</html>

 

12.原型链上成员访问规则

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>
<script>
  /* 
    如果一个对象访问成员,在对象上没有找到,会沿着原型链查找
    就近原则
    1.如果当前对象身上有自己该成员,优先使用该成员
    2.如果当前对象身上没有该成员,沿着原型链寻找
    3.如果直到尽头.还没有找到,返回undefined
    
    
     */
  function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  Person.prototype.gender = "男";
  Person.prototype.height = 185;
  var p = new Person("鲨鱼辣椒", 14);
  console.log(p.name);
  console.log(p.age);
  console.log(p.gender);
  console.log(p.height);
  console.log(p.weight);

  console.log(Array.prototype);
  console.log(Object.prototype);
  console.log([1, 2, 3].toString());
  // console.log(Array.toString());
</script>

</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值