JavaScript高级应用

1.原型链

构造函数创建一个对象

function Dog() {

}
var dog = new Dog();
dog.name = '旺财'
console.log(dog);//Dog { name: '旺财' }

prototype

每个函数都有一个 prototype 属性

function Dog() {

}
//注意:prototype是函数才会有的属性
Dog.prototype.name = '小红'
var dog1 = new Dog();
var dog2 = new Dog();
console.log(dog1.name); //小红
console.log(dog2.name); //小红

构造函数与实例原型之间的关系
在这里插入图片描述

__proto__

每一个js对象(null除外)都具有该属性,这个属性会指向该对象的原型。

function Dog() {

}
var dog = new Dog()
console.log(dog.__proto__ == Dog.prototype); //true

在这里插入图片描述

constructor

每个原型都有一个 constructor 属性指向关联的构造函数

function Dog() {

}
var dog = new Dog()
console.log(Dog === Dog.prototype.constructor); //true

在这里插入图片描述
综上:

function Dog() {

}

var dog = new Dog()

console.log(dog.__proto__ == Dog.prototype); //true
console.log(Dog.prototype.constructor == Dog); //true
//es5中获取对象原型的方法
console.log(Object.getPrototypeOf(dog) === Dog.prototype); //true

原型链

function Dog() {

}
Dog.prototype.name = "七七"

var dog = new Dog();

dog.name = "胡桃"

console.log(dog.name); //胡桃

delete dog.name;
console.log(dog.name)//七七

在这里插入图片描述

console.log(Object.prototype.__proto__ === null) // true

在这里插入图片描述

2.词法作用域,动态作用域

  • 词法作用域:js使用的是词法作用域,在函数定义的时候就决定了函数的作用域。
  • 动态作用域:函数的作用域是在函数调用的时候菜决定的
var val = 1;

function run() {
    console.log(val);
}

function go() {
    var val = 333
    run()
}

go()//1

3.执行上下文栈

观察下面两段代码:

var run = function() {
    console.log('run1');
}
run()//run1
var run = function() {
    console.log('run2');
}
run()//run2
function go() {
    console.log('go1');
}
go()//go2

function go() {
    console.log('go2');
}
go()//go2

出现这种差异的原因是:
js引擎并非一行一行的分析和执行程序,而是一段一段的分析执行。当第一段代码执行时,会进行一个“准备工作”。比如第一个例子中的变量提升,第二个例子中的函数提升。

4.可执行代码

全局代码、函数代码、eval代码

举个例子,当执行到一个函数的时候,就会进行准备工作,这里的“准备工作”,让我们用个更专业一点的说法,就叫做"执行上下文(execution context)"。
(待续…)

5.闭包

在这里插入图片描述

var a=1;
function run(){
	console.log(a);
}
run();

run()函数+run()能够访问的自由变量=闭包

6.防抖

前端中会频繁触发的事件有:
1.window中resize,scroll
2.mouseover,mousedown
3.keyup,keydown

要解决频繁触发的事件有两种方案:
1.debounce 防抖
2.throttle 节流

防抖的原理:你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行。

<input type="text" id="btn">
<script>
    // console.log(btn);
    btn.oninput = function() {
        console.log(this.value);
    }
</script>

这段代码,在你操作表单的时候会一直输出
在这里插入图片描述
现在我们要用防抖来实现:我停止输入的行为之后才输出表单里面的内容

<input type="text" id="btn">
<script>
  // console.log(btn);
  btn.oninput = debounce(function() {
      console.log(this.value);
  }, 500)

  function debounce(fn, delay) {
      var timer = null
      return function() {
          var _that = this

          if (timer) {
              clearTimeout(timer)
              timer = null
          }

          timer = setTimeout(function() {
              //切换对象拿到btn的this
              fn.apply(_that)
              clearTimeout(timer)
              timer = null
          }, delay)
      }
  }
</script>

效果:

7.节流

节流实现每1.5s只执行一次

<input type="text" id="btn">
<script>
 // console.log(btn);
 btn.oninput = debounce(function() {
     console.log(this.value);
 }, 1500)

 function debounce(fn, delay) {
     var timer = null
     return function() {
         var _that = this

         if (timer) {
             return
         }

         timer = setTimeout(function() {
             //切换对象拿到btn的this
             fn.apply(_that)
             clearTimeout(timer)
             timer = null
         }, delay)
     }
 }
</script>

参考:
https://github.com/mqyqingfeng/Blog/issues

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值