自学JavaScript高级第二天

76 阅读5分钟

JavaScript高级第二天

1.函数定义和调用

  	  //普通函数 this指向window
      function fn() {
          console.log(this)
      }
      fn();
      fn.call();
      // 对象的方法 this指向实例对象原型对象里面的方法也指向实例对象
      var o = {
        sing: function () {
          console.log(this);
        },
      };
      o.sing();
      // 构造函数  该访法所属对象
      function Star() {}
      new Star();
      // 绑定事件  绑定事件对象
      // btn.noclick =function() {}//通过点击事件
      // 定时器调用  window
      // setTimeout(function() {},2000) //会自动调用
      // 立即执行函数  window
      // (function(){})()自动执行

2.this指向

这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同
一般指向我们的调用者.
调用方式	 this指向
普通函数调用 	window
构造函数调用 	实例对象原型对象里面的方法也指向实例对象
对象方法调用 	该访法所属对象
事件绑定方法	 绑定事件对象
定时器函数 	  window
立即执行函数   window

3.改变this指向的方法

1.call方法

call()可以改变this的指向

        function all (a,b){
            console.log(this)
            console.log(a+b)
        }
        var o = {
            name: "and"
        }

        all(3,4)
        //call()可以改变this的指向 这里让他指向o
        all.call(o,5,3)

借用父结构函数

1.传值

   function Father(uname,password){
      this.uname =uname
      this.password = password
  }
  function Son (uname,password){
  		//父级调用call 让父级的this 指向sub的this
		Father.call(this,uname,password)
  }
  var son =new Son('ldh',123456)
  console.log(son.password)

2.传方法

//让子类的prototype 指向一个新的构造函数(Father)
Son.prototype = new Father( );
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son.prototype.constructor = Son;

2.apply方法

        var o ={
            username: "andi"
        }
        function fn (uname){
            console.log(uname)//张三
            console.log(this)
        }
        fn.apply(o,['张三'])

//1.也是调用函数第二个可以改变函数内部的this指向 //2.但是他的参数必须是数组(伪数组) // 3. apply 的主要应用比如说我们可以利用apply 借助于数学内置对象求最大值 // Math. max();

        var arr =[1,5,3,2,66,3,2,444,2]
        //因为apply传的是数组 但解析出来的是数字型 所以可以使用Math方法
        
        var max = Math.max.apply(Math,arr)
        console.log(max)

3.bind方法

var o ={
    username: "andi"
   }
function fn (a,b){
 	console.log(a+b)
    console.log(this)
}
//不会执行 因为他是返回一个新的对象
//fn.bind(o,1,2)
var f =fn.bind(o,1,2)
f()

  1. 不会调用原来的函数 可以改变this指向

  2. 返回的是原函数改变this之后产生的新函数

  3. 如果有一个函数不需要立即调用 ,但是又想改变里面this的指向就可以用bind

    1. 例如点击按钮后三秒禁用后重新可以执行
            var btn =document.querySelector('button')
            btn.onclick = function() {
                console.log('aaaa')
                // 点击禁用
                this.disabled=true
                // 三秒后重新开启
                setInterval(function(){
                    this.disabled = false
                }.bind(this),1000)
            }
    

4.call apply bind总结

相同点: . 都可以改变函数内部的this指向. 区别点:

  1. call和apply会调用函数,并且改变函数内部this指向.

  2. call 和apply传递的参数不一样, call传递参数aru1, aru2..形式apply必须数组形式[arg]

  3. bind 不会调用函数,可以改变函数内部this指向.

主要应用场景:

1.call经常做继承.

2.apply 经常跟数组有关系.比如借助于数学对象实现数组最大值最小值

3.bind 不调用函数但是还想改变this指向.比如改变定时器内部的this指向.

4.严格模式

严格模式就是规范代码

//全部的严格模式
<script>
	'use strict'    
</script>
//立即执行的严格模式
<script>
	(function(){
    'use strict'  
	})()  
</script>

//单个函数进行严格模式
function fn(){
    'use strict'  
}

5.高阶函数

高阶函数就是 接受的参数是一个函数 或者 返回值是一个函数

 function  fn(a,b,callback){
            console.log(a+b)
            callback && callback()
        }
// 接受的参数是一个函数
        fn(1,4,function(){
            console.log('我是高阶函数')
        });
//返回值是一个函数
function fn1(){
    return function(){
        
    }
}
fn1()

6.什么是闭包

//闭包(closure)指有权访问另一个函数作用域中变量的函数。 //一个作用域可以访问另外一个函数的局部变量 //我们fn外面的作用域可以访问fn内部的局部变量 优点 //闭包的主要作用:延伸了变量的作用范围 缺点 如果一直使用内部函数的变量导致不会销毁从而导致内存泄露 解决 用完这个变量把他设置成null

应用场景有防抖节流 防抖存定时器的id 可以清除定时器 节流存储默认开关 达到什么时候关什么时候开

function fn(){
        var num = 10
        // 返回一个函数 (就是高阶函数) 
        // 返回一个函数带着num的值
        return function fn1(){
            console.log(num)
        }
    }
    // 通过调用fn把返回值赋值给f 这个f也是个函数所以能够调用
    var f = fn()
    f()

7.什么是递归

递归就是自己调用自己

记住一定要用return 退出循环

         // 利用递归的阶层1~n的阶层 n*....5*4*3*2*1
        function fn(n){
            // 如果没遇到1就继续执行
            if (n==1){
                return 1
            }
            // n * fn(n-1) 一直重新调用
            return n * fn(n-1)
        }
        fn()

8.深拷贝浅拷贝

浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用. 深拷贝拷贝多层,每一级别的数据都会拷贝. Object.assign( target, ... sources) es6 新增方法可以浅拷贝

Object.assign(拷贝到的地方,拷贝源) //浅拷贝 如果有对象的只是拷贝了对象的地址

深拷贝

46165f2cc48ab9316a7737e75d5e77b.png