1.this指向 理解this指向只需明白两种情况 1.函数执行时,看前面是否有“点”,“点”的前面是谁,this就指向谁;没有点,this就指向window 例如: fn() this=>window obj.fn() this=>obj obj.__proto__.fn() this=>obj.__proto__
//具体实例 1
function fn() {
console.log(this.name);
};
let obj = {
name: '行星飞行',
func: fn,
};
let obj1 = {
name: '听风是风',
o: obj
};
obj1.o.func() //行星飞行 this指向obj1.o=》obj => obj.name = "行星飞行" 所以输出行星飞行
// 特殊情况:作为参数传递以及变量赋值,this的指向会丢失
//具体实例 2
var name = '行星飞行';
let obj = {
name: '听风是风',
fn: function () {
console.log(this.name);
}
};
function fn1(param) {
param();
};
fn1(obj.fn);//行星飞行
// obj.fn没有立即执行,而是作为参数传递给了 fn1 ,所以原来的this丢失了,它被fn1调用了,fn1前面没有点,所以指向window
2.给元素的事件行为绑定方法时,(DOM/DOM2),事件触发方法会执行,此时方法中的this指向元素本身 box.onclick = function(){console.log(this)} => this => box box.addEventListener = function(){console.log(this)} => this => box
2.变量提升 在执行上下文执行之前,会把带var和function关键字的进行提升 带var的,只是提前声明 带function的,会提前声明+定义
fn();
function fn(){ console.log(1); }
fn();
function fn(){ console.log(2); }
fn();
var fn = function(){ console.log(3); }
fn();
function fn(){ console.log(4); }
fn();
function fn(){ console.log(5); }
fn();
/* 最终输出结果为 5 5 5 3 3 3
在执行上下文变量提升阶段:
fn = AAAFFF111 => 1
= AAAFFF222 => 2
= AAAFFF444 => 4
= AAAFFF555 => 5 (变量提升阶段完成,fn=AAAFFF555)
所以fn最终指向的是输出5的那个fn
在代码执行阶段,前三个输出的就是5,遇到变量声明var fn = ... 时,fn被赋值为输出3的函数
因此最后输出3 3 3 */
3.惰性函数 简单来说,惰性函数就是优化一个需要被多次调用的函数,使其更高效,也可以说是函数更懒惰了,所以称之为惰性函数 例:
//普通思维:封装一个 执行 DOM2 事件的函数
function emit(element, type, func) {
if (element.addEventListener) {
element.addEventListener(type, func, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, func);
} else {
element['on' + type] = func;
}
}
// 用惰性函数的思维:进行判断过是否支持该方法后,执行将此函数重新赋值,那么下一次执行时,函数则不会再走那么多if else 判断,变得“懒惰”了
function emit(element, type, func) {
if (element.addEventListener) {
emit = function (element, type, func) {
element.addEventListener(type, func, false);
};
} else if (element.attachEvent) {
emit = function (element, type, func) {
element.attachEvent('on' + type, func);
};
} else {
emit = function (element, type, func) {
element['on' + type] = func;
};
}
emit(element, type, func);
}
emit(box, 'click', fn1);
emit(box, 'click', fn2);
4.柯里化函数 简单理解就是一个大函数返回一个小函数 利用闭包的机制,把一些内容事先存储和处理了,等到后期需要的时候拿来即用即可 例如bind方法的实现就是如此
//例1:bind方法的实现:
(function(proto){
function bind(context,...args){
let _this = this;
return function proxy(){
_this.call(context,...args)
}
}
proto.bind = bind;
})(Function.prototype)
let obj = {a:1}
function func (number){
this.a = number + 2;
console.log(this)
}
setTimeout(func.bind(obj,10),1000)
//例2:利用闭包的原理实现一个模块,此处也是用了柯里化函数编程思想:利用闭包,将一些内容事先存储了,以后拿来用即可
let newsModule = (function(){
let URL = 'https://www.ljt.com';
function queryData(){
return URL+' queryData'
}
function setData(){
return URL+' setData success !!'
}
return {
queryData
}
})()
let result = newsModule.queryData()
console.log(result)