JS面向?qū)ο?基礎(chǔ))

一、面向過(guò)程和面向?qū)ο蟮膮^(qū)別、聯(lián)系

1.面向過(guò)程編程:注重解決問(wèn)題的步驟,分析問(wèn)題需要的每一步,實(shí)現(xiàn)函數(shù)依次調(diào)用。

2.面向?qū)ο缶幊?注重問(wèn)題中的對(duì)象,分析問(wèn)題中對(duì)象的聯(lián)系,實(shí)現(xiàn)對(duì)象間的通訊解決問(wèn)題.面向?qū)ο缶幊痰^(guò)程,強(qiáng)調(diào)對(duì)象 更貼近我們?nèi)巳粘L幚韱?wèn)題的方式。

3.面向過(guò)程:所有功能都是在需要使用的時(shí)候才開(kāi)發(fā),相當(dāng)于去餐館點(diǎn)菜,現(xiàn)點(diǎn)現(xiàn)做,需要等。

4.面向?qū)ο?在正式開(kāi)發(fā)之前,就先把所有需要使用的功能都開(kāi)發(fā)好,并以屬性或者方法的形式存放

在一個(gè)對(duì)象中,在實(shí)際開(kāi)發(fā)的時(shí)候根據(jù)需要來(lái)調(diào)用寫好的功能。相當(dāng)于去快餐店吃快餐,菜都是

事先已經(jīng)炒好的,去了就可以吃。


二、什么是對(duì)象?什么是面向?qū)ο螅?/h1>

1.對(duì)象是類的實(shí)例。對(duì)象是具體的事物。

2.只有對(duì)象才有屬性和方法,基本數(shù)據(jù)類型沒(méi)有,string等類型能夠使用的方法來(lái)自他自身的構(gòu)造器,在基本數(shù)據(jù)類型調(diào)用方法時(shí)會(huì)臨時(shí)創(chuàng)建一個(gè)對(duì)象出來(lái),在方法完成時(shí)自動(dòng)銷毀。

3.對(duì)象,黑盒子,是一個(gè)整體,對(duì)外提供一些操作,不了解內(nèi)部的結(jié)構(gòu),知道表面的各種操作(按鈕)。

4.面向?qū)ο蠛?jiǎn)單的來(lái)說(shuō)就是:不了解原理的情況下,會(huì)使用功能。面向?qū)ο笫且环N通用思想,并非只有編程中能用,任何事情都可以用。

5.面向?qū)ο缶幊桃步蠴OP,特點(diǎn):①抽象,抓住核心問(wèn)題,把最主要的、跟問(wèn)題相關(guān)的特征抽出來(lái)。②封裝:不考慮內(nèi)部實(shí)現(xiàn),只考慮功能使用。簡(jiǎn)單說(shuō):就是看不到里面的東西,用好表面的功能。③繼承(遺傳):從已有對(duì)象上,繼承出新的對(duì)象。多重繼承。多態(tài)。從父類上繼承出一些方法、屬性,子類,又有一些自己的特性。多重繼承:可以同時(shí)繼承多種父級(jí)的特性

6.對(duì)象的組成:①方法--函數(shù):過(guò)程、動(dòng)態(tài)的②屬性--變量:狀態(tài)、靜態(tài)的。

7.變量和屬性的不同:變量是自由的,不屬于任何人。屬性是有歸屬的,屬于一個(gè)對(duì)象的。

//定義一個(gè)對(duì)象

//直接量

//var obj={};

//使用Object聲明對(duì)象

var ?obj= new ? Object();

//覆蓋式的定義方式,

var ? ?person={

name:"張三",

age:"18",

hobby:function() {

console.log("我喜歡籃球");

}

}

//后面的會(huì)覆蓋前面的

//var person = {

//name: "李四"

//}

//追加屬性和方法

person.height="178cm";

console.log(person)

//調(diào)用

person.hobby();

console.log(person.name);

對(duì)象數(shù)組,一個(gè)數(shù)組里面有多個(gè)對(duì)象

var ?phoneNumber=[{

name:"coco",

tel:"132432432"

}, {

name:"popo",

tel:"5840583"

}]

//取到里面的東西

//console.log(phoneNumber[0].name)

//如果數(shù)據(jù)比較多,需要用循環(huán)

for? (var? i=0; i<phoneNumber.length;i++){

console.log(phoneNumber[i].name);

}

var ? person={

name:"張三",

height:"189cm"

}

//獲取對(duì)象里面的東西,如果數(shù)據(jù)比較多,也可以循環(huán)

//key下標(biāo) ? ? ? ? value值

for(var ?k ? in ? person) {

console.log(k);//對(duì)象的下標(biāo)

console.log(person[k]);//獲取單個(gè)值

}


三、工廠模式

并不常用,每次調(diào)用函數(shù)都重新定義了函數(shù),(函數(shù)重復(fù),資源浪費(fèi))

//工廠模式

function ? ?factory(name,age) {//類

var ? obj={};

obj.name=name;

obj.age=age;

obj.hobby=function() {

console.log("sing");

}

return ? ? obj;

}

//直接調(diào)用

factory().hobby();//sing

//用參數(shù)接收調(diào)用

var ? ? newFactory=factory("張三","18");//對(duì)象

newFactory.hobby();

console.log(newFactory.name);

//不用傳參,用arguments,如果參數(shù)不確定的情況下,就用arguments

function ? factory() {

//console.log(arguments);

var ? obj={};

obj.name=arguments[0];

obj.age=arguments[1];

obj.hobby=function() {

console.log("sing");

}

return ? obj;

}


四、構(gòu)造函數(shù)

//創(chuàng)建構(gòu)造函數(shù),類似于類

function Student(name,sex){

//屬性

this.name = name;

this.sex = sex;

//方法

this.intro = function(){

alert("姓名:" + this.name + "\n" + "性別:"+this.sex);

}

}

使用構(gòu)造函數(shù)

//創(chuàng)建對(duì)象

var student = new Student("張三","男");

//調(diào)用方法

student.intro();

構(gòu)造函數(shù):用來(lái)構(gòu)建對(duì)象的函數(shù)。

注意:1.為了區(qū)別普通函數(shù),構(gòu)造函數(shù)的函數(shù)名首字母規(guī)定應(yīng)該為大寫。2.構(gòu)造函數(shù)必須使用new運(yùn)算符來(lái)調(diào)用執(zhí)行(實(shí)例化對(duì)象)。3.在構(gòu)造函數(shù)里面寫屬性,在原型里面寫方法


五、原型

1.通過(guò)new實(shí)例化出來(lái)的對(duì)象,其屬性和行為來(lái)自于兩個(gè)部分,一部分來(lái)自于構(gòu)造函數(shù),另一部分來(lái)自于原型.

2.當(dāng)我們聲明一個(gè)類時(shí),其實(shí)同時(shí)生成了一個(gè)對(duì)應(yīng)的原型.例如我們定義Person這個(gè)類時(shí),會(huì)產(chǎn)生一個(gè)與Person類對(duì)應(yīng)的原型prototype.

3.原型本身就是一個(gè)對(duì)象。

4.通過(guò)prototype可以指向這個(gè)原型,原型可以通過(guò)constructor指向Person類(構(gòu)造函數(shù)).

function? Dog(){//構(gòu)造函數(shù)

? ? ? ?this.name="大黃";

? ? ? ? this.sex="公";

}

Dog.prototype={//原型

? ? ? bark:function(){

? ? ? alert("汪汪~(yú)");

? ? ? ? ?}

}

//也可以這樣寫

//通過(guò)構(gòu)造函數(shù)找到原型

Car.prototype={

action1:function() {

console.log("我是方法1")

},

action2:function() {

console.log("我是方法2")

},

}

//原型

//Car.prototype.action = function() {

//console.log("我是原型里的方法");

//}

function ?Person() {

this.arr=[1,2,3];

}

//通過(guò)原型可以取到構(gòu)造函數(shù)里面的東西

Person.prototype.hobby=function() {

console.log(this.arr);

}

var ? newPerson= newPerson();

newPerson.hobby();


六、原型鏈

1.原型鏈:原型鏈?zhǔn)侵笇?duì)象在訪問(wèn)屬性或方法時(shí)的查找方式。

2.當(dāng)訪問(wèn)一個(gè)對(duì)象的屬性或方法時(shí),會(huì)先在對(duì)象自身上查找屬性或方法是否存在,如果存在就使用對(duì)象自身的屬性或方法。如果不存在就去創(chuàng)建對(duì)象的構(gòu)造函數(shù)的原型對(duì)象中查找 ,依此類推,直到找到為止。如果到頂層對(duì)象中還找不到,則返回 undefined。

3.原型鏈最頂層為 Object 構(gòu)造函數(shù)的 prototype 原型對(duì)象,給 Object.prototype 添加屬性或方法可以被除 null 和undefined 之外的所有數(shù)據(jù)類型對(duì)象使用。


七、公有和私有

1.在傳統(tǒng)的面向?qū)ο蟮恼Z(yǔ)言中一般會(huì)提供public、protected、private等關(guān)鍵字來(lái)聲明屬性和方法的

公開(kāi)性.

2.javascript中沒(méi)有這些關(guān)鍵字,我們通過(guò)作用域來(lái)實(shí)現(xiàn)公有或者私有。

functionWomen(name,sex){

//公有屬性

this.name=name;

this.sex=sex;

//私有屬性

var_age="30";

//公有方法

this.eat=function(){

alert("");

}

//私有方法

var ?fight=function(){

alert("!");

}

}

對(duì)于上述例子中,使用this.xxx定義的屬性和方法是公有的,我們?cè)谕獠渴褂脤?duì)象很容進(jìn)行訪問(wèn).

使用 var xxx定義的屬性和方法是私有的.只能在構(gòu)造函數(shù)內(nèi)部進(jìn)行直接訪問(wèn).


set方法:我們可以通過(guò)公有的方法去訪問(wèn)私有的屬性.我們把給專門給私有屬性賦值的方法稱為set方法

get方法:我們把專門獲取私有屬性的方法稱為get方法

function ? ? Women(name){

? ? ? this.name=name;

? ? ? var ? ? _age="30";

? ? ? //set方法

? ? this.setAge=function(age){

? ? ? ? ?_age=age;

? ? ?}

}

function ? ?Women(name){

? ? ? this.name=name;

? ? ?var_age="30";

? ? ?//get方法

? ? this.getAge=function(){

? ? ? ? return ? ? _age;

? ? }

}


八、繼承

1.繼承的目的是找到類之間的共性,精簡(jiǎn)代碼。

2.原型不能直接被繼承

//解決繼承中原型的傳址問(wèn)題

function ? ?Dad() {

this.name="楊冪";

this.age=18;

}

Dad.prototype.hobby=function() {

console.log("電視");

}

function ? ?Son() {

this.name="小糯米";

Dad.call(this);

}

//創(chuàng)建一個(gè)新的對(duì)象就會(huì)新引用一個(gè)地址

Son.prototype= newDad();

Son.prototype.hobby=function() {

console.log("肉肉");

}

var ? ? ?newDad= new ? Dad();

newDad.hobby();


九、改變this指向

//下面三種方式可以改變this指向

var ? o={

name:"張三",

age:"18"

}

function? test(name,age) {

?console.log(this);

}

//這時(shí)候this指向window

//test();

//通過(guò)call改變函數(shù)內(nèi)部的this指向

//這時(shí)候this指向o

//test.call(o)

var ? ?o={

name:"張三",

age:"18"

}

function ? test(name,age) {

console.log("姓名"+name+"年齡"+age)

console.log(this);

}

//test.call(o,"張三",18)

//test.apply(o,["李四",36]);//第二個(gè)參數(shù)需要的是一個(gè)數(shù)組

//test.bind(o)("王五", 21);


十、傳值和傳址

傳址:復(fù)雜的數(shù)據(jù)類型就會(huì)涉及到傳址問(wèn)題

傳值:簡(jiǎn)單的數(shù)據(jù)類型,(一個(gè)簡(jiǎn)單的變量就是簡(jiǎn)單的數(shù)據(jù))

//傳值

var ?a=10;

var ? b=a;

var ? ?b=5;

console.log(a)//10

//傳址

var ?arr1=[1,2,3,4];

var ? arr2=arr1;

arr2[1]=5;

console.log(arr1);//[1,5,3,4]

//傳址

var ? obj1={

name:"coco",

age:18

};

var ? obj2=obj1;

obj2.age=10;

console.log(obj1)//{name:"coco",age:10}

//傳址造成的問(wèn)題案例

function ? Dad(height) {

this.name="王健林";

this.height=height;

this.money="$88888888888";

this.hobby=function() {

console.log("太極");

}

}

//js面向?qū)ο罄锩娴睦^承,原型是不會(huì)被繼承的

Dad.prototype.fun=function() {

console.log("高爾夫");

}

functionSon(height) {

this.name="王思聰";

//繼承(就相當(dāng)于把this指向的函數(shù)加到Dad里面)

//Dad.call(this, height);

//Dad.apply(this, [height]);

Dad.bind(this)(height);

}

//解決不能繼承原型的問(wèn)題

//這種方式,造成了兩個(gè)fun的地址是在一起,改變一個(gè),另一個(gè)也會(huì)被改變,傳址

Son.prototype=Dad.prototype;

Son.prototype.fun=function() {

console.log("泡妞");

}

var ? newDad= new ? ?Dad();

newDad.fun();//泡妞


十一、深拷貝(克?。?/h1>

1.JSON.stringify()? 將 [] 或 {} 的對(duì)象轉(zhuǎn)換成字符串形式的值,就是編碼

2.JSON.parse()? 將字符串形式的 [] 或 {} 值轉(zhuǎn)換成對(duì)象,就是解碼

3.克隆實(shí)現(xiàn)原理:利用字符串賦值為傳值的特點(diǎn),先將對(duì)象轉(zhuǎn)換成字符串形式,然后將字符串形式的值再轉(zhuǎn)換成對(duì)象。

4.兼容問(wèn)題:不支持低版本IE瀏覽器

//解決傳址問(wèn)題

//深拷貝,克隆

var ? obj1={

name:"coco",

age:18

};

//編碼json數(shù)據(jù)

//var _json = JSON.stringify(obj1);

//console.log(_json)

//console.log(typeof ?_json) //string

//解碼json串

//var obj2 = JSON.parse(_json);

//console.log(obj2);

//用深拷貝解決傳址問(wèn)題

var ? ? obj2=JSON.parse(JSON.stringify(obj1));

obj2.age=13;

console.log(obj1);


十二、typeof的不足

typeof 可以準(zhǔn)確地判斷出簡(jiǎn)單數(shù)據(jù)類型,但對(duì)復(fù)雜數(shù)據(jù)類型的判斷相對(duì)比較模糊。

比如: 數(shù)組對(duì)象 \ 時(shí)間對(duì)象 \ 正則對(duì)象 \ Math對(duì)象等都返回的是 ‘object’。

優(yōu)化方案:封裝函數(shù)
function type( obj ){

var o = {};

return o.toString.call(obj).slice(8,-1).toLowerCase();

}

實(shí)現(xiàn)原理:Object 對(duì)象的 prototype 的 toString() 方法會(huì)返回一個(gè)表示對(duì)象本身類型的字符串。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容