面向對象: 對代碼的一種抽象,對外統一提供調用介面的編程思想 對象的屬性:事物自身擁有的東西 對象的方法:事物的功能 對象:事物的一個實例 對象的原型:.prototype -> 記憶體地址 -> 存儲了一個對象 function fn(){ return 1; } alert(fn.prototyp ...
面向對象:
對代碼的一種抽象,對外統一提供調用介面的編程思想
對象的屬性:事物自身擁有的東西
對象的方法:事物的功能
對象:事物的一個實例
對象的原型:.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
閉包
閉包是一個擁有許多變數和綁定了這些變數的環境的表達式(通常是一個函數)
全局變數在函數內部可以訪問
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
用途:1、讀取函數內部變數 2、讓函數內部變數保留在記憶體中,不隨著函數的執行結束而被銷毀
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