一、面向過(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ì)象本身類型的字符串。