JS面向对象

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

案例:

输出: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]); //取得是属性的值 或者是方法的定义代码
}

输出: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中的特权方法和属性,没有继承共有方法和属性
原文地址:https://www.cnblogs.com/chenyingying0/p/12144822.html