一,三者的定义和使用
function A(){
//1,定义实例属性和方法
this.name1 = 'name1';
this.show1 = function () {
console.log('show1');
};
}
//2,定义原型属性和方法
A.prototype.name2 = 'name2';
A.prototype.show2=function(s){
console.log('show2');
};
//3,定义静态属性和方法
A.name3 = 'name3';
A.show3 = function () {
console.log('show3');
}
//1,使用实例属性和方法
var a=new A();
console.log(a.name1);
a.show1();
//2,使用原型属性和方法
console.log(A.prototype.name2);
A.prototype.show2();
//3,使用静态属性和方法
console.log(A.name3);
A.show3();
结果:
name1
show1
name2
show2
name3
show3
二,实例属性和实例方法
- 实例属性地址不同,实例方法写在内部地址不同,写在外部地址相同(优化)
- 构造函数内部的对象的属性和方法:
-
function CreateObject(name,age){
this.name=name; //实例属性
this.age=age;
this.run=function(){ //实例方法
return this.name + this.age;
}
}
var box1 = new CreateObject('ZHS',100);
var box2 = new CreateObject('ZHS',100);
console.log(box1.run() == box2.run());//true 比较方法的返回值
console.log(box1.run == box2.run); //false 比较方法的引用地址
结果:
true
false
- 实例方法写在外部
-
var fns = {
run:function(name,age){
return this.name + this.age;
}
}
function CreateObject(name,age){
this.name=name; //实例属性
this.age=age;
this.run=fns.run;
//可以设置全局方法来实现引用地址一致性 .会出现问题
//this.run = run;
}
var box1 = new CreateObject('ZHS',100);
var box2 = new CreateObject('ZHS',100);
console.log(box1.run == box2.run); //true 比较的是引用地址
结果:
true
-
三,原型属性和原型方法
- 不在构造函数中定义的属性和方法;
- 原型属性地址不同,原型方法地址相同
-
function CreateObject(height){
this.height = height;
}
CreateObject.prototype.name='ZHS';//原型属性
CreateObject.prototype.age='100';
CreateObject.prototype.run=function(){
return this.name + this.age;
}//原型方法
var CreateObject1 = new CreateObject();
var CreateObject2 = new CreateObject();
console.log(CreateObject1.run() == CreateObject2.run()); //true
console.log(CreateObject1.run == CreateObject2.run); //true
结果:
true
true
四,静态属性和静态方法
- 通过构造函数直接调用的属性和方法
- 静态属性和静态方法都是绑定在构造函数上,是类的属性,而非实例对象this的属性
- 静态属性
-
Foo {
}
Foo.prop = 1;
console.log(Foo.prop) // 1
结果:
1
- 静态方法
-
function Foo() {
}
//定义在Foo类上
Foo.static = function () {
console.log('static fun')
}
Foo.static() //类可以调用
结果:
static fun
五,三者的区别
- 静态的属于类,实例的属于对象(this),而原型就是值为自身对象的静态属性(this.prototype)
- js静态属性和方法必须在类外面定义,而实例属性和方法、原型属性和方法则没有这个限制,类的里面和外面都可以定义
-
//写法报错TypeError: A.show1 is not a function
function A(){
A.show1=function(s){
console.log("method 1 hello "+s+"!")
}
}
A.show1("tang");
//写法正常
function A(){
}
A.show1=function(s){
console.log("method 1 hello "+s+"!")
}
A.show1("tang");
- 实例方法内调用实例方法和实例属性,必须用this
-
function A(){
this.show2=function(s){
console.log("method 2 hello "+s+"!");
};
this.show3=function(s){
this.show2(s);
//不能写成show2(s);
};
}
var a=new A();
a.show3("tang");
结果:
method 2 hello tang!
- 调用原型属性和方法时可以将前面的”类名.prototype.”改成”对象.”。
改成”对象.”的调用原理:首先在实例对象中查找,如果找到则立即返回,否则在prototype中查找,找到则返回相应的值,否则返回undefined
-
function A(){
A.prototype.show1=function(s){
console.log("method 1 hello "+s+"!");
};
}
var a=new A();
a.show1("tang");
A.prototype.show1("zhi");
结果:
method 1 hello tang!
method 1 hello zhi!
- 总之:
- 静态属性是全局的,
- 原型属性是实例公有的,
- 实例属性是各个实例所独有的
五,获取实例对象的实例属性和方法
console.log(a);//实例对象
console.log(a.constructor);//只是原型对象的构造器
console.log(a.name1);
a.show1();
结果:
A { name1: 'name1', show1: [Function] }
{ [Function: A] name3: 'name3', show3: [Function] }
name1
show1
六,获取原型对象的原型属性和方法
console.log(a.__proto__);//原型对象
console.log(a.__proto__.constructor);
console.log(a.__proto__.name2);
a.__proto__.show2();
结果:
A { name2: 'name2', show2: [Function] }
{ [Function: A] name3: 'name3', show3: [Function] }
name2
show2
七,获取类对象的静态属性和方法
console.log(A);//类对象
console.log(A.constructor);
console.log(A.name3);
A.show3();
结果:
{ [Function: A] name3: 'name3', show3: [Function] }
[Function: Function]
name3
show3
-