微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JS面向对象

Object 是javascript 父对象

function F(){ //自定义函数

}
alert(F.prototype); 函数原型是object对象  
alert(F.prototype instanceof Object); true

闭包 全局变量函数内部可以访问

function a(){
    var i = 0;
     b(){
        alert(++i);
    }
    return b;
}
var c = a();
c(); 1

闭包的优缺点

优点: 有利于封装,可以访问局部变量

缺点: 内存占用浪费严重,内存泄漏

 f1(){
    var n = 999;
    nAdd = (){
        n = n+1;
    }
     f2(){
        alert(n);
    }
     f2;
}
var rs =f1();
rs(); 999
nAdd();  --->执行了
rs(); 1000

案例:

输出:11/12

闭包的原理是,把局部函数赋值给全局变量,由于全局变量代码执行的过程中是不会销毁的,所以它用到的值即局部函数不会销毁。而局部函数中使用到的变量也就保存在内存中了。

var func=test()执行之后 ,func实际的值是subTest函数。当局部函数subTest赋值给了全局变量func后,内部用到的变量n保存在内存中。n的认值是10,func()第一次调用,执行subTest函数,n自加1,弹出n的值是11。func()第二次调用,n自加1,弹出的值为12

 

 

闭包实现点击li显示点击了哪个

<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <title>2-1</title>
    <style>
        /*补充代码*/
        li{
            cursor:pointer;
        }
    </style>
</head>
<body>
    <ul>
        <li>选项1</li>
        <li>选项2</li>
    </ul>
    <!-- 补充代码 -->
    <script>
        var li=document.getElementsByTagName("li");
        for(var i=0,len=li.length;i<len;i++){
            ((i){
                补充代码
               li[i].onclick=(){
                       alert(i);
               }            
           })(i)
        }
    </script>
</body>
</html>

对象的声明:

字面式=json方式

var person = {
    name:"zhangsan",age:26(fds){
        alert("我在吃"+fds);
    },play:(ga){
        alert("我在玩"+ga);
    }
}
alert(person.age);
person.eat("面条");
alert(person instanceof Object);

Object方式

var Box = new Object();
Box.name = "zhangsan";
Box.age = 100;
Box.infos = (str){
    return this.name+"---"+this.age+"---"+str; this 当前对象
}
alert(Box.name);
var con = Box.infos("吃饭那");
alert(con);

构造函数

 person(name,sex,age){
    this.name = name;  this.name属性     name参数 习惯上 属性名称==参数
    this.sex  = sex;
    this.age  = age;
    this.show = (){
        alert(this.sex+"---"+this.age);
    }
}
var obj1 = new person("zhangsan","nan",18);
alert(obj1.sex);
obj1.show();
var obj2 = new person("lisi","nv",20);
obj2.show();
注意: this 代表当前对象,obj1和obj2两者之间是独立的,函数内部只能用this访问属性方法

构造和 工厂模式 不同:

1 构造方式不会显示创建对象 将属性赋值给 this ,不需要return 对象

2 工厂 在方法内部创建 object对象  返回object对象 ,属性方法都是赋给object对象

 createObject(name,1)">var obj =  Object();
    obj.name = name; obj.name 属性  name参数
    obj.age  = age;
    obj.run = function(){ 在obj对象中 调用obj对象的属性 this 代表的当前对象***
        this.name +"----" + this.age +"运行中....";  
    }
    obj.say = (){
        return "今天天气不错" obj;
}
var Box1 = createObject("张三",1)">);
alert(Box1.name); 调用属性成功
alert(Box1.run()); 调用方法成功
var Box2 = createObject("李四",1)">);
alert(Box2.name);
alert(Box2.run());

原型模式1

 test(){
}
alert(test.prototype instanceof Object); //自带该对象 prototype是Object子对象
test.prototype.color     = "red";
test.prototype.heights     = "1.7";
test.prototype.widths     = "1.2";    
test.prototype.showInfo             = (){
    alert(this.color+"---"+this.heights+"---"+.widths);
}
test.prototype.getinfo             = (){
    alert("aaaaa");
}
var car1 =  test();
car1.getinfo();

原型模式2

json数据定义属性方法
test.prototype={
    color:"red".widths);
    },getinfo:(str){
        alert(str);
    }
}
 test();
car1.getinfo("abc");

混合模式:构造+原型

 blog(name,url,friend){
    this.name     = name;
    this.url    = url;
    this.friend    = friend;
}
blog.prototype={
    test:"awt".url);
    },gets:.friend);
    }

}
var peo = new blog("张三","http://www.baidu.com","李四");
peo.showinfo();

对象的遍历

 

for in  取到的值是该对象-obj的所有属性名及方法

 ren(){
    this.name="zhangsan"this.age = "18"this.leng="180"this.demo = .name);
    }
}
var r =  ren();
var i in r){ i是属性方法名称
    alert(r[i]); 取得是属性的值 或者是方法的定义代码
}

输出:aaa aaabbb aaabbbfunction(){alert(“ccc”)}

for in 的遍历过程就相当于循环取值,能取到多少个值,就执行多少次函数体。对象遍历时,可以当做数组一样处理,通过[]取值

 

 

函数封装:

 A(){
    var t = 3function _xx(){ alert(11+"****") ;}
    this.xx =  _xx;
    }
}
A.prototype = {
    oth:(){
        alert("普通方法");
    }
}
var a =  A();
var b = a.xx();  a.xx()  ---> function _xx()
//b();
a.oth();
 缺陷: 1 占用内存  2 不利于继承

原型继承

原型的值可以是一个对象,也可以是null。通过”Object.prototype._proto_”获取Object原型的原型的时候,将会得到”null”,也就是说”Object {}”原型对象就是原型链的终点了;

继承的时候,允许多传参,多传入的参数会被截取掉,不起作用;

 

var person = (){};
person.prototype.say = (){
    alert("天气挺好");
}
person.prototype.gongzi = 500;

var programmer = (){};
programmer.prototype = new person();programmer的原型继承自person
programmer.prototype.wcd = (){
    alert("明天天气也不错");
}
programmer.prototype.gongzi=1000;


var p =  programmer();
p.say(); 可以调用person的方法
p.wcd(); 可以调用programmer的方法
alert(p.gongzi); 1000

原型继承:用到原型链的概念

function person(name,age){
    this.name=this.age = age;
}
person.prototype.sayhello = (){
    alert("属性name值"+.name);
}
function student(){} ;
student.prototype = new person("李四",18); 原型继承
student.prototype.grade = 3;
student.prototype.test = .grade);
}
var  s =  student();
s.sayhello();李四
alert(s.grade);3

js 继承:

call apply

call --》 obj.call(方法,var1,var2,var3....)

apply--> obj.apply(方法,[var1,var3]);

this.name =this.len = len;
    this.say = this.name+":"+this.age+":"+.len);
    }
}
call继承
 student(name,age){
    person.call(apply继承
 teacher(name,len){
    person.apply(var per = new person("张三",25,"170");
per.say();
var stu = new student("李四",1)">);
stu.say();  李四 18 undefined
var tea = new teacher("王武",20,"180");
tea.say();

关键词:

instanceof  变量是否是对象的实例

delete 删除对象的属性

 fun(){
    this.name = "zhangsan" fun();

alert(obj.name);
delete obj.name; 删除name属性
alert(obj.name);undefined 


var demo = "lisi";
alert(demo);
delete demo; 删除不了变量
alert(demo);
注意:delete 不能删除原型链中的属性和变量

call apply

 animal(){
    this.name = "ani"this.showName =  cat(){
    this.name = "cat";
}
var an =  animal();
var c =  cat();
an.showName.call(c,",");  通过call方法,将showName--》cat使用了
an.showName.apply(c,[]);

callee:返回正在执行的function对象,function 内容

arguments.callee  认值 正在执行的function对象

var sum = (n){
    if(n<=1){
        return 1;
    }else{
        return n+arguments.callee(n-1); 函数内部调用函数
    }
}
alert(sum(5));

arguments.length,参数个数

arguments.callee 引用函数自身

 test(a,b,c){
    alert(arguments.length);
    alert(arguments[1]); arguments如果是表示参数,可以遍历的
    alert(arguments.callee);
}
test(1,2,3);

this 可以在函数内部定义属性/变量

this全局变量 global

var x = 1;
 test(){
    this.x = 0 改变了 全局变量 x 值
}
test();
alert(x);

构造函数内 this指当前对象

this.name = "zhangsan"; this表示当前对象 --》 t
    this.age = 18var t =  test();
alert(t.name);

在call  apply中,this指第一个参数

var x = 0 test(){
    alert(.x)
}
var o = {};
o.x = 1;
o.m = test
o.m.apply(); 一个参数指向全局变量x:0
o.m.apply(o); 一个参数指向对象o中的变量:1;

运用apply实现两个数组的拼接

        var a=[1,3];
        var b=[4,5,6];
        a.push.apply(a,b);
        console.log(a);

对象冒充

this.sayHi = (){
        alert("hi");
    }
}
person.prototype.walk = (){
    alert("walk......"this.newMethod = person; 冒充person对象,传递特权属性和特权方法给子类
    .newMethod(name,age)
    this.grade = grade;
}
var s1 = new student("zhangsan",15,5); s1 是student 对象 ,继承person,拥有person所有属性方法
s1.sayHi();
注意 s1继承了 person中的特权方法属性,没有继承共有方法属性

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐