一、this
表示代码运行时,是哪个对象让它运行的。
案例一:
var obj = {
life: 1,
name: "karen",
vip: true,
books: ["book1", "book2"],
sayname: function() {
console.log(6666); //打印 666
console.log(this); //打印obj整个对象
}
};
console.log(obj.books); //打印["book1", "book2"]
console.log(obj.life); //打印1
console.log(obj.sayname); //打印函数体function() { console.log(6666); console.log(this); }
obj.sayname(); //对象调用方法,运行函数
console.log(obj.sayname());
//sayname()运行结果为:打印 666 打印obj整个对象
//console.log(obj.sayname()) 打印undefined(函数的默认返回值)
案例二:
var obj = {
name: "karen",
age: 30,
son: {
name: "jack",
age: 1,
say: function()
{ console.log(this.name, 1111); }
},
say: function()
{ console.log(this.name, 222); }
};
console.log(obj.son); //打印son对象 name: "jack",age: 1,say: f
obj.say() //打印karen,222
console.log(obj.son.age) //打印1
obj.son.say() //打印jack 1111
//分析:调用的是son这个对象的say函数,所以this指的对象是son,打印this.name就是son的name属性值,jack
obj.son.x=100 //在son内添加一个成员:x:100
obj.son.say2 = obj.say; 在son内添加一个成员:say2:function() { console.log(this.name, 222); }
obj.son.say2(); //打印 jack 222
//分析:调用son中的say2函数,所以this指的对象是son,打印this.name就是son的name属性值,jack
案例三:
var obj = {
name: "karen",
son: {
name: "jack",
say: function() {
this.fn(); //obj.son.fn()
}
},
fn: function() {
console.log(this.name, 6666);
}
};
// obj.son.say()
obj.son.fn = obj.fn;
obj.fn(); //karen 6666
obj.son.fn(); //jack 6666
obj.son.say(); //jack 6666
任何函数调用都有对象在调用,默认为window,也就是说fn()是window.fn()的简写。
二、new
1. 创建对象的基本写法
1. 直接写对象(对象直接量)
2. 通过函数(构造的函数)创建对象
例:
function Person(){
}
var obj1=Person();
var obj=new Person();
console.log(obj1); // 打印undefined
console.log(obj); // 打印一个空对象
2. new的用法
1. 创建一个对象 空对象{ }。然后给这个空对象添加一个属性:__proto__。这个属性的值,就是构造函数的prototype属性中保存的对象。
2. 用这个创建的空对象去调用函数 eg: {}.Person() , obj.say()
3. 整个new表达式会得到一个对象
如果函数返回值是一个引用数据,new得到的对象就是这个返回值
如果函数返回值是一个基本数据,new得到的对象就是构造函数中的this对象
三、闭包
1. 含义:具有独立作用域的代码块,能访问外层作用域变量值的一种设计。因此所有函数都是闭包。
2. 使用场景
1. 保护数据
//由于: 函数内部可以访问函数外部变量 但是不能访问内部变量: 保护数据
// 如果一个函数内部的变量 外部想访问,又不能直接访问: 这个函数可以返回一个内部的函数 然后这个内部的函数来操作这个函数内部的变量
function fn () {
var user={name:"karen",money:100}
return user
}
var re=fn();
console.log(re);
re.money=900 //这个设计不合理 因为外部直接修改了函数内部的数据
//解决办法:闭包
function fn () {
var user={name:"karen",money:100}
return function tool (m) {
//验证调用tool的代码是否合法
user.money=m
}
}
var re=fn();
re(90);
2. 实现临时保存数据
// 利用了函数调用栈的独立作用域,来实现临时: 保存数据
var arr=[{name:"karen"},{name:"jack"}]
console.log(arr[0].name)
for(var i=0;i<2;i++){
arr[i].say=function(){console.log(i)}
}
console.log(i,"-----------------------")
/*
var arr=[{name:"karen",say:function(){console.log(i)}},{name:"jack",say:function() {console.log(i)}}]
var i=2;
0<2 ==>
arr[0].say=function(){console.log(i)}
i++
1<2 ==>
arr[1].say=function(){console.log(i)}
i++
2<2 ==>
for结束
*/
arr[0].say()//0 0
/*
function(){console.log(i)}
console.log(i)
*/
arr[1].say()//1 1
3. 防止变量污染,生成闭包块