一,this的指向问题
<script>
console.log(this) //window
function a(){ console.log(this)} // window,因为a挂载在window上
let obj = {
username:'张三',
fn:function(){
console.log(this.username);
}
}
obj.fn() //这里的this指向obj
window.obj.fn() //也没问题
//这个例子告诉你this指向上一个调用者
var j = {
a:10,
b:{
a:12,
fn:function(){
console.log(this) //这里的this指向b
}
}
}
var id=66;
function fn(){
setTimeout(()=>{
console.log(this.id)
},500)
} //箭头函数没有定义域,没有this,所以会去上一级的上一级找,此时this是window,所以id为66
fn({id:55})
//那么如何指向当前的id?
//call(),apply(),bind()
</script>
call(),apply(),bind()三者的区别:
call()和apply()的第一个参数都是传入this指向的对象,他们的区别是apply的第二个参数必须是一个数组(第二个参数是传入函数的参数)
例如:getData.call(person,’xx’) getData.apply(person,[“xx”])
而bind()和上面两者的区别是bind()返回一个函数,而不是立即执行一次(上面那俩都是会立即执行一次)
例如:const getData1 = getData.bind(person,”xx”); getData1(“xx”);
二,闭包
为什么会出现闭包?
- 避免变量被污染。
- 私有化。
- 保存变量,常驻内存。
AO = Active Object,指临时变量对象,方法和局部变量都会在AO里边,当函数执行完之后就会被回收。而全局变量会常驻内存。相应的闭包也有这种情况。
一个简单的例子:
(function(){
let a = 2;
function b(){};
return{
a,b
}
})
应用场景:
- 防抖,节流
- 库的封装(保证数据私有性)
三,new关键字
let a = new Person()
//执行过程
//1,创建一个空对象
let obj = Object.create(null) //完全的空对象,不含有任何原型和方法,适用于只存值的情况
let obj2 = {};
//1,创建一个空对象
let obj = new Object();
//2.设置它的原型链
obj._proto_ = Person.prototype;
//3,改变this的指向
let result = Person.call(obj);
//4,判断返回值类型
if(typeof (result)=="Object"){
person1 = result;
}else{
person1 = obj;
}
普通函数返回值默认返回undefined,构造函数默认返回新创建的对象。
四,事件委托
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一个类型的所有对象。
<body>
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<button id="btn">
点我添加一个li
</button>
</body>
<script>
let ul = document.getElementById("ul");
ul.onclick = function(event){
console.log(event)
event = event||window.event
let target = event.target
if(target.nodeName == 'LI'){
alert(target.innerHTML)
}
let btn = document.getElementById("btn")
btn.onclick =function(){
let li = document.createElement("li")
li.textContent = ul.children.length
ul.appendChild(li)
}
}
</script>