面向对象
- 类,原型,实例三者打交道
- 类里面存放的都是私有属性和方法
- 原型prototype上存的都是公有的属性和方法
- 类里面的this都指向实例
- 类里面的this跟var没有任何关系,var是用来预解释的
- 类里面会自动帮我们创建和返回this
对象:属性 和 方法
写面向对象的小窍门
- 把全局变量都作为私有属性
- 把全局函数都作为公有方法
- 面向对象中的this,永远执行实例
属性判断:判断某个属性,是否在某个对象上
- in 公有+私有:"attr" in obj => true / false
- hasOwnProperty 是否为私有: fl.hasOwnProperty('attr')=>true / false
- hasPubProperty 是否为公有(不是系统提供的,是自己写的)
- 思路:必须是元素身上的属性,并且不是私有属性
function hasPubProperty(attr,obj){ if(attr in obj && !obj.hasOwnProperty(attr)){ return attr; } }
- isPropertyOf 判断是否在原型链上:obj1.isPropertyOf(boj2)
循环遍历
- for...in...循环:只能遍历自己给对象添加的私有属性+公有属性,不能遍历对象的系统属性
- hasOwnProperty和propertyIsEnumerable,都可以遍历自己定的私有属性,不能遍历公有属性和系统自带的属性
关于Object和Function之间的关系
- 对象的老大 Object
- 函数的老大 Function
- Object是Function的爹
- Function是Object这个基类的爹
- Object.prototype是Function.prototype的爹
- 所有的对象,都可以使用Object.prototype上的方法
- 但是,只有函数数据类型,才能使用Function。prototype的方法,因为所有函数数据类型是Function这个类的实例
函数的三种角色
- 普通函数->作用:预解释 作用域链 上级作用域 代码从上到下执行
- 类->作用:类 原型 实例 原型链
- 对象->作用:跟普通的对象一样, 都可以添加属性和方法
Function.prototype
- Function.prototype虽然是个匿名函数,但是他具有普通prototype一样的功能
call apply bind
- fa.call():有两类参数
- 第一个参数:用来改变call前面函数中this关键字的指向
- 从第二个参数开始:给call前面的函数从左到右,一个个的传参
- call改完this,传完参数之后,函数会“立即执行”
- fa.apply():有两个参数 -> 跟call功能一样,但是传参形式不同
- 第一个参数:用来改变apply前面函数中this关键字的执行
- 第二个参数(数组):也是给apply前面的函数从左到右,一个个的传参
- fa.bind():预处理机制
- 参数跟call一样
- bind()给前面的函数,改完this,传完参后,不会立即执行,只会返回一个函数的定义阶段;
- 在需要的地方调用
this小总结
- 当元素身上的事件被触发的时候,会执行一个函数,函数中的this执行当前这个元素
- 当函数被调用的时候,看前面是否有点,点前面是谁,this就是谁,没有点,this就是window
- 自执行函数中的this,永远指向window
- 回调函数中的this,一般指向window,但是可以通过thisArg更改this指向
- 构造函数中的this,指向实例;
- 当遇到call、apply、bind的时候,以上规则全失效,他们三个就是用来更改this指向的
继承
- call继承:子类只继承父类“私有”的属性和方法,不继承公有
<script>
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
var s1 = new Son;
console.dir(s1);
</script>
- 拷贝继承:子类只继承父类“公有”的属性和方法,不继承私有
<script>
// 通过此方法继承的公有在第一个__proto__上
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
</script>
- 原型链继承:子类把父类私有和公有的属性和方法,都放在自己的prototype上
<script>
//通过此方法继承,公有在__proto__找到的__proto__上
function extend(obj){
function Tmp() {}
Tmp.prototype = obj.prototype;
return new Tmp;
}
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){};
S.prototype = new F;
var s1 = new S;
console.dir(s1);
</script>
- 混合式继承:call继承+拷贝继承
// 最后S继承的属性位置和F一样
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){
F.call(this);
}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
- 寄生式组合继承
function setCreat(obj){
function Tmp(){}
Tmp.prototype = obj.prototype;
return new Tmp();
}
function F() {
this.a = 1;
this.b = 2;
}
F.prototype.c = 3;
F.prototype.d = function () {};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
Son.prototype = setCreat(F);
var s1 = new Son;
console.dir(s1);
可视区的宽度和高度
- 宽度:document.documentELement.clientWhidth || document.body.clientWidth
- 高度:document.documentElementlientHeight || document.body.clientHeight