面向对象
基于原型的面向对象
基于原型的面向对象方式中,对象(object)则是依靠构造器(constructor)利用原型(prototype)构造出来的.
function F(argument) { //自定义函数
}
alert(F.prototype); //对象 F.prototype --> 内存地址 --> 存储一个对象
//构造函数对象:函数构造器 创建函数对象
var obj = new Function(var1,var2,...,functionBody());
//var1,var2 functionBody() 自定义函数
- 注意:构造器构造的对象,效率低,var1,var2 顺序在functionBody中不能变
- 对象 --> 函数对象,普通对象 new Function创建的都是函数对象
闭包
- 用途:读取函数内部变量 让i变量的值保留在内存中
- 优缺点:封装性强 可以访问局部变量 内存占用浪费,容易引起内存泄漏
function a(){
var i = 0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c(); //1
声明对象
第一种 字面式
var obj = {
var obj = {
name : 'greentea',
age : 23,
do : function(){
console.log('do...');
}
}
第二种
var obj = new Object();
obj.name = 'greentea';
obj.age = 23;
第三种 构造函数
function test(a,b,...){
this.name = wang;
this.do = function(){
//...
}
}
var obj = new test(a,b,...)
工厂模式创建对象
工厂模式创建对象不需要new,并且要返回一个对象,而构造函数创建对象需要new一个对象,还要将this返回
function createObject(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + this.age;
}
return obj;
}
var box1 = createObject('zhangsan',21);
var box2 = createObject('lisi',18);
原型模式创建对象
function test(){
}
test.prototype.play = 'lol';
test.prototype.do = 'papa';
test.prototype.eat = function(){
console.log('mm');
}
var obj = new test();
构造加原型
function test(){
this.color = 'red';
}
test.prototype.play = 'lol';
test.prototype.do = 'papa';
test.prototype.eat = function(){
console.log(this.color);
}
var obj = new test();
对象的遍历
var person = {};
person.name = 'zs';
person.age = 23;
for(var i in person){ //i是属性或方法名称
alert(ren[i]); //取得属性值或方法体
}
封装
function demo(){
var n = 1; //局部变量,外部不能直接访问
function test(){
return n++;
}
return test;
}
alert(demo()()); //2
原型链继承
原型:是利用
prototype
添加属性和方法
原型链:JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__
的内置属性,用于指向创建他的函数对象的原型对象prototype
原型链的概念实现原型继承
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function(){
alert('属性name值' + this.name);
}
function Student(){
this.style = 'play';
}
Student.prototype = new Person('lisi',18);
Student.prototype.grade = 3;
Student.prototype.test = function(){
alert(this.grade);
}
构造函数继承
在子类内部构造父类的对象实现继承
function Parents(name){
this.name = name;
this.say = function(){
alert('父亲的名字:'+this.name);
}
}
function Child(name,age){
this.pObj = Parents;
this.pObj(name);
this.age = age;
this.sayC = function(){
alert('child:' + this.name + '---' + 'age:' + this.age);
}
}
var p = new Parents('zhangsan');
p.say();
var c = new Child('lisi',20);
c.sayC();
call和apply的用法
call:调用一个对象的方法,以另一个对象替换当前对象
apply:应用某一对象的一个方法,用另一个对象替换当前对象
obj.call(function(){},var1,var2,var3...)
obj.apply(function(){},[var1,var2,var3...])
function person(name,age,len){
this.name = name;
this.age = age;
this.len = len;
this.say = function(){
alert(this.name + ":" + this.age + ":" + this.len);
}
}
//call继承
function student(name,age){
person.call(this,name,age);
}
//apply继承
function teacher(name,age,len){
person.apply(this,[name,age,len]);
}
var per = new person('zhangsan',25,170);
per.say();
var stu = new student('lisi',18);
stu.say(); //lisi 18 undefined
delete
- 只能删除属性,不能删除方法
- 删除不了变量
- 不能删除原型链中的属性和变量
callee
调用本函数,如果没有条件约束,将陷入死循环
var sum = function(){
if(n<=1){
return 1;
}else{
return n+arguments.callee(n-1); //在函数内部调用本函数
}
}