概念
1.类----〉对象:通过类造的对象,所有的都是一个模板。
在js中对象不依赖于类而存在,直接造对象,例:json格式的对象
2.其它语言中类中的方法或属性是不能删除的。
.js的对象属性,也是可以任意添加和删除的
obj = {};
obj.win = 2;
delete obj.win;
总结:
1. js中的对象,就是一组属性与值的集合
2. 属性和方法可以任意增减
3. 不必须区分属性和方法
封装 ##
封装:
封闭一部分,外界无法访问
开放一部分,通过开放部分来间接的访问封闭的(闭包)
闭包完成js封装:
function girl(name,bf){
var secret = bf;
this.name = name ;
//做接口,来读取私有属性secret
this.love = function(){
return secret;
}
}
var girl = new girl('wo','qing');
alert(girl.name+":"+girl.love());
继承
1.原型继承
继承:
1.通过 原型 来完成继承的。
例:猫对象<<-------老虎构造函数----------->>老虎对象 :老虎继承猫
照猫画虎:
明确对 老虎函数 指定,用某个具体的 猫对象 做老虎的原型,并创造老虎对象
function tiger(){
this.bark = function(){
alert('百兽之王');
}
}
var huzi = new tiger();
huzi.bark();//百兽之王
function cat(){
this.climb = function(){
alert('我会爬树');
}
}
var mao = new cat();
//mao.climb();//我会爬树
//老虎的原型指向了猫对象 ,这时老虎继承了猫
tiger.prototype =mao;
huzi = new tiger();
/*
* 发生了什么:
* 1.构造空对象 huzi{};
* 2.huzi.bark = function(){};
* 3.huzi._proto_ = tiger.prototype (即猫对象) 这时继承的关键
*
* 在js中每个对象,都有一个_proto_ 指向其原型对象
* 原型对象也是对象,也有_proto_
*
* 原型的原型的原型的原型: 对象总有原型
* 默认原型,其实是空对象,空对象上有一个construct 构造属性
* construct属性 又指向 new出来的对象,所有空对象表现出自己本身,而不是object
* console.log(cat.prototype);
*
* 空对象原型默认指向 object, object原型指向 null
*
* 原型链: 对象-----〉 原型------〉原型的原型-------〉object对象 ----------〉null
* 老虎对象有什么属性 先找猫对象,即老虎的原型,猫再找自已的原型,猫的原型
* 如果是空的,空的原型是object ,object的原型再找 null
*
*
* */
huzi.climb();//new 出来的对象有了猫的方法了
console.log(huzi);
console.log(mao);
console.log(cat.prototype);//空对象,显示为cat
console.log(cat.prototype.constructor); //因为默认原型对象的constructor指向cat构造函数,所以显示为cat
console.log(cat.prototype.__proto__);//空对象原型:是 object对象
console.log(cat.prototype.__proto__.__proto__); // object原型: 是null
**总结:
对象的属性和方法,就是沿着原型链来查找和调用的,这就是js中的原型继承**
实例1
//所有new 出来的对象都有了sing 的方法
Object.prototype.sing = function(){
alert('唱');
}
function pig(){
this.eat = '30kg';
}
var p = new pig();
p.sing();
2.原型冒充
function cat(leg,tail){
this.leg = leg;
this.tail = tail;
this.climb = function(){
alert('我会爬树');
}
}
function tiger(leg,tail,cor){
//把要继承的语句,拿来执行一遍
this.parent = cat;
this.parent.apply(this,arguments);
delete this.parent; //没有必要要这个属性了,所有可以删除;
this.color = cor;
}
var tig = new tiger('4','1','yellow');
console.log(tig);
tig.climb();
/**
解:
其实就是 在用tiger造对象时,用tiger的语句影响一个空对象{}
在此过程中,tiger影响空对象前,先由cat函数实施影响
因此,最终得到的对象,是由 cat和tiger两者共同作用过的对象;
**/
3.复制继承
function cat(leg,tail){
this.leg = leg;
this.tail = tail;
this.climb = function(){
alert('我会爬树');
}
}
function tiger(cor){
this.color = cor;
this.extend = function(parent){
for(var key in parent){
//console.log(key);
this[key] = parent[key];
}
}
}
var tig = new tiger('yellow');
tig.extend(new cat(4,1));
console.log(tig); //已经有cat的属性了
//复制继承:就是把父对象的所有属性,直接复制到自已对象上
var BaseClass = function() {
this.method1 = function(){
alert(' Defined by the "this" in the instance method');
}
};
var instance1 = new BaseClass();
instance1.method1 = function(){
alert(' Defined directly in the instance method');
}
BaseClass.prototype.method1 = function(){
alert(' Defined by the prototype instance method ');
}
instance1.method1();//Defined directly in the instance method
通过运行结果跟踪测试可以看出直接定义在实例上的变量的优先级要高于定义在“this”上的,
而定义在“this”上的又高于 prototype定义的变量。即直接定义在实例上的变量会覆盖定义
在“this”上和prototype定义的变量,定义在“this”上的会覆盖prototype定义的变量。
var BaseClass = function() {
var method1 = function() {
alert("Internal method");
};
var method2 = function() {
alert("call Internal method");
method1();
};
this.method3 = function(){
method2();
}
};
var instance1 = new BaseClass();
instance1.method1();// 会报错,因为method1是BaseClass中定义的内部变量,作用域只有在内部可见(闭包)
instance1.method3();//会先后调用method2和method1