转载于网络
this
- this是一个对象
- 他的值随着代码的运行而改变
- 到处都有this
不能手动改变this,不能出现在=的左边
this出现在函数的外部
this 指向window
this出现在函数的内部
若this出现在对象方法的内部那么就指向这个对象
若不是方法的内部而只是普通函数的内部仍然指向window
若用构造函数创建一个对象,那么构造函数中的this就指向生成的对象
通过call/apply来修改函数中的this指向
字面量
var obj = {
name: 'hanker',
speak: function(){
return 'hello ' + this.name;
},
age: 20
}
- 属性之间没有顺序的分别
- 方法直接访问该对象的属性和方法前要加this
- 属性名字可以加”,’也可以不加
- 也可以先定义一个空对象,然后给这个空对象添加属性和方法
var obj = {};
obj.name = 'hanker';
obj.age = 20
obj.speak = function(){
return 'hello ' + this.name;
}
上面要访问该对象的属性要使用this.name来获得hanker
优点:简单
缺点:不能批量生成
工厂模式
思想:用一个函数来初始化一个空对象
function createObj(w,h){
var obj = {};
obj.width = w;
obj.height = h;
obj.getArea = function(){
return this.width * this.height;
}
return obj;
}
console.log(createObj(10,10).getArea());//100
优点:快速创建对象
缺点:生产的对象缺少标识符
function createObj(w,h){
var obj = {};
obj.width = w;
obj.height = h;
obj.getArea = function(){
return this.width * this.height;
}
return obj;
}
var r1 = createObj(10,10);
var r2 = createObj(20,20);
console.log(r1.constructor);//function Object() { [native code] }
console.log(r2.constructor);//function Object() { [native code] } 没有分开两个对象
构造器
function F(name,age){//构造器一般首字母大写
this.name = name;
this.age = age;
this.speak = function(){
return this.name +' '+ this.age;
}
}
var me = new F('hanker',20); // 首先会执行一下 F();
console.log(me.speak()); // hanker 20
console.log(me.constructor); // F
过程
- 创建一个空对象 var obj = {};
- F.apply(obj,[augument]);
- obj.proto == F.prototype;
- 返回obj
优点:
- 简单
- 有标志符
- 面向对象思想
缺点:
它的自有属性(特别一些方法)会重复。如下:每个对象都有一个speak方法。而这个方法显然应该是全体的对象都有的,而不需要每一个对象都有一个。这样会造成空间的浪费。
原型方式创建对象
function F(name,age){
this.name = name;
this.age = age;
}
F.prototype.speak = function(){
return this.name +' ' + this.age;
}
var me = new F('hanker',20); // 首先会执行一下 F();
var you = new F('xxx', 21);
console.log(me.speak()); // hanker 20
console.log(you.speak()); // xxx 21
console.log( you.__proto__ == me.__proto__); // true
注意:
- 把每个对象用的方法放在原型中
- 创建对象的时候必须加上new,不然只会调用一下函数,函数中的this指向window
原型属性和对象自有属性
function Reat(){
this.width = 100;
this.height = 100;
}
Reat.prototype.name = 'juxing'
name这个属性是每个new Reat都有的属性
width 自有属性,每一个对象自己的属性
相同点:
每一个对象都可以访问
不同点:
修改对象的原型每个对象都会受到影响
function Reat(x,y){
this.width = x;
this.height = y;
}
Reat.prototype.name = 'juxing'
var f1 = new Reat(10,20);
var f2 = new Reat(100,200);
f1.name = 'f1 juxing';
console.log(f1.name); // f1 juxing
console.log(f2.name);// juxing
f1.__proto__.name = 'f1 juxing';
console.log(f1.name);// f1 juxing
console.log(f2.name);// f1 juxing
过程
当f1.name首先去寻找自有属性,如果没有则通过原型链去找
如果通过f1.proto.name去修改则所有通过Reat来创建的对象的原型链上的name都被修改了
如果f2本身没有自有的name属性,那么就向上寻找原型链中的name属性
注意:
console.log(f1.hasOwnProperty(‘name’)); // true
console.log(f2.hasOwnProperty(‘name’)); //false
在原型链上的属性可以通过hasOwnProperty来查询
for(var p in f1){
console.log(p); //width height name
}
for(var p in f2){
console.log(p); //width height name
}
通过for in 能遍历出自有属性和原型属性
同理原型方法和自有方法