欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JS面向对象

程序员文章站 2022-04-14 16:46:04
Object 是javascript 父对象 function F(){ //自定义函数 } alert(F.prototype); //函数原型是object对象 alert(F.prototype instanceof Object); //true 闭包 全局变量在函数内部可以访问 funct ......

object 是javascript 父对象

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

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

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

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

闭包的优缺点

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

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

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

案例:

JS面向对象

输出: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++){
            (function(i){
               // 补充代码
               li[i].onclick=function(){
                       alert(i);
               }            
           })(i)
        }
    </script>
</body>
</html>

对象的声明:

字面式=json方式

var person = {
    name:"zhangsan",
    age:26,
    sex:"man",
    eat:function(fds){
        alert("我在吃"+fds);
    },
    play:function(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 = function(str){
    return this.name+"---"+this.age+"---"+str; //this 当前对象
}
alert(box.name);
var con = box.infos("吃饭那");
alert(con);

构造函数

function person(name,sex,age){
    this.name = name;  //this.name属性     name参数 习惯上 属性名称==参数
    this.sex  = sex;
    this.age  = age;
    this.show = function(){
        alert(this.name+"---"+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对象

function createobject(name,age){
    var obj = new object();
    obj.name = name;// obj.name 属性  name参数
    obj.age  = age;
    obj.run = function(){ //在obj对象中 调用obj对象的属性 this 代表的当前对象***
        return this.name +"----" + this.age +"运行中....";  
    }
    obj.say = function(){
        return "今天天气不错";
    }
    return obj;
}
var box1 = createobject("张三",18);
alert(box1.name); //调用属性成功
alert(box1.run()); //调用方法成功
var box2 = createobject("李四",20);
alert(box2.name);
alert(box2.run());

原型模式1

function 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             = function(){
    alert(this.color+"---"+this.heights+"---"+this.widths);
}
test.prototype.getinfo             = function(){
    alert("aaaaa");
}
var car1 = new test();
car1.getinfo();

原型模式2

function test(){
}
//json数据定义属性和方法
test.prototype={
    color:"red",
    heights:"1.7",
    widths:"1.2",
    showinfo:function(){
        alert(this.color+"---"+this.heights+"---"+this.widths);
    },
    getinfo:function(str){
        alert(str);
    }
}
var car1 = new test();
car1.getinfo("abc");

混合模式:构造+原型

function blog(name,url,friend){
    this.name     = name;
    this.url    = url;
    this.friend    = friend;
}
blog.prototype={
    test:"awt",
    showinfo:function(){
        alert(this.name+"---"+this.url);
    },
    gets:function(){
        alert(this.friend);
    }

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

对象的遍历

 

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

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

JS面向对象

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

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

 


 

函数封装:

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

原型继承

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

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

 

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

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


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

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

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

js 继承:

call apply

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

apply--> obj.apply(方法,[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("张三",25,"170");
per.say();
var stu = new student("李四",18);
stu.say(); // 李四 18 undefined
var tea = new teacher("王武",20,"180");
tea.say();

关键词:

instanceof  变量是否是对象的实例

delete 删除对象的属性

function fun(){
    this.name = "zhangsan";
    this.say = function(){
        alert(this.name);
    }
}
var obj = new fun();

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


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

call apply

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

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

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

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

arguments.length,参数个数

arguments.callee 引用函数自身

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

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

this全局变量 global

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

构造函数内 this指当前对象

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

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

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

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

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

对象冒充

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