面向對象+閉包+三種對象的聲明方式(字面式、new Object、構造函數、工廠模式、原型模式、混合模式)

面向對象:javascript

對代碼的一種抽象,對外統一提供調用接口的編程思想html


 

對象的屬性:事物自身擁有的東西java

對象的方法:事物的功能編程

對象:事物的一個實例json

對象的原型:.prototype -> 內存地址 -> 存儲了一個對象閉包

    function fn(){
        return 1;
    }
    alert(fn.prototype);//[object Object]

經過new Function建立的對象是函數對象,其餘的都是普通對象函數

var obj=new Function(n1,n2,n3,...functionBody());
//構造函數對象  前面是一系列參數,後面是自定義函數體
//不過構造器構造的對象,效率比較低
//參數順序不能改變,必須一一對應

var add=new Function("a","b","return a+b");
var sum=add(3,5);
alert(sum);//8

閉包this

閉包是一個擁有許多變量和綁定了這些變量的環境的表達式(一般是一個函數)spa

全局變量在函數內部能夠訪問prototype

var n=100;
function fn(){
    alert(n);//100
}
fn();

函數內部的變量,在外部不能訪問

function fn(){
    var n=100;
}
fn();
alert(n);//報錯 n is not defined

有時須要在外部訪問函數內部的變量

解決方法:在函數內部再定義一個函數,輸出須要的變量,而後將該內部函數做爲返回值

function fn(){
    var n=100;
    function fn2(){
        alert(++n);
    }
    return fn2;
}
fn()();//101

閉包:函數b在函數a內嵌套,函數a須要返回函數b

用途:一、讀取函數內部變量  二、讓函數內部變量保留在內存中,不隨着函數的執行結束而被銷燬

function fn(){
    var n=100;
    nAdd=function(){
        n++;
    }
    function fn2(){
        alert(n);
    }
    return fn2;
}
var res=fn();//將fn()賦值給變量後,內部變量不會在每次執行時被初始化
res();//100
nAdd();
res();//101

閉包的優缺點:

優勢-有利用封裝,能夠訪問局部變量

缺點-內存佔用,容易產生內存泄漏

閉包可使用,但要謹慎使用


 

在html中建立任意幾個li,利用閉包特性實現點擊li彈出它的索引值

var lis=document.querySelectorAll("li");

for(var i=0;i<lis.length;i++){
    (function(i){
        lis[i].onclick=function(){
            alert(i);
        }        
    })(i);
}

匿名函數自調用,傳入了for循環裏面的i值,保存每一次循環的i值

for循環會先執行完畢,而後造成多個做用域

每一個i值會做爲實參傳入函數中,當點擊li的時候,彈出的i值就是做用域中的i值

 

 字面式聲明對象-最基本的方式

//字面式
var person={
    name:"cyy",
    age:25,
    eat:function(food){
        alert("我在吃"+food);
    }
}
console.log(person.name);//cyy
person.eat("西瓜");//我在吃西瓜
console.log(person instanceof Object);//true

new Object() 構造函數

Object是全部對象的基類,全部javascript對象都是由object延伸的

//new Object()構造函數
var person=new Object();
person.name="cyy";
person.age=25;
person.infos=function(str){
    return this.name+" "+this.age+" "+str;//this指向當前對象
}
alert(person.infos("很可愛"));//cyy 25 很可愛

構造方法聲明對象

使用new來實例化

函數內部只能用this來訪問屬性和方法

//構造方法聲明對象
function Person(name,age){
    this.name=name;//this.name是屬性 name是參數
    this.age=age;
    this.show=function(){
        alert(this.name+" "+this.age);//this指向當前對象,不一樣的實例對象是獨立的
    }
}
var cyy=new Person("cyy",25);
cyy.show();//cyy 25

var cyy2=new Person("cyy2",18);
cyy2.show();//cyy2 18

工廠方式聲明對象:按照某種模式,能夠不斷的創造對象

在一個函數內部使用 new Object() 建立一個對象,而且返回這個對象

//工廠模式
function person(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.infos=function(){
        return this.name+" "+this.age+" 很可愛";//對象的方法中要調用屬性,必須使用this
    }
    return obj;
}
var cyy=person("cyy",25);
alert(cyy.infos());//cyy 25 很可愛

var cyy2=person("cyy2",25);
alert(cyy2.infos());//cyy2 25 很可愛

// cyy和cyy2二者沒有聯繫

構造方式和工廠模式的區別:

構造方式不會建立出一個對象,也不會返回這個對象,將屬性賦值給this


 

原型模式聲明對象

任何js方法或者函數,都自帶prototype屬性,而且以對象方式存在

函數自己聲明爲空內容,經過prototype聲明屬性和方法,最後new這個函數

//原型模式
function person(){

}
//alert(person.prototype);//[object Object]
person.prototype.name="cyy";
person.prototype.age=25;
person.prototype.infos=function(){
    return this.name+" "+this.age;
}

var p=new person();
alert(p.infos());//cyy 25

原型模式也能夠以json數據的方式來定義屬性和方法

//原型模式
function person(){

}

//json數據格式
person.prototype={
    name:"cyy",
    age:25,
    infos:function(){
        alert(this.name+" "+this.age);
    }
}

var p=new person();
p.infos();//cyy 25

混合模式:構造模式+原型模式

//混合模式:構造+原型
function person(name,age){
    this.name=name;
    this.age=age;
}

person.prototype={
    addr:"China",
    infos:function(){
        alert(this.name+" "+this.age+" "+this.addr);
    }
}

var p=new person("cyy",25);//構造函數部分須要傳參,原型部分直接定義
p.infos();//cyy 25 China
相關文章
相關標籤/搜索