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