面向對象之構造函數、實例對象、原型

1、面向對象
首先有一個需求,點擊按鈕改變div的樣式。按照常規的思惟來寫,咱們多是先獲取到目標元素,而後給目標元素添加事件,在事件中書寫div須要改變的樣式屬性。以下:javascript

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var btn = document.getElementById('btn');
btn.onclick = function(){
var div = document.getElementById('div1');
div.style.height = '300px';
div.style.width = '300px';
div.style.backgroundColor = 'green';
}
}
</script>
</head>
<body>
<div style="width: 200px;height: 200px;border:1px solid red;" id="div1"></div>
<input type="button" value="點擊" id="btn">
</body>
</html>

 


可是隨着事件的增多,代碼的量也隨之加大,若是點擊的按鈕不止一個,是否是又得將點擊事件的代碼重寫一遍?這樣維護起來也不方便;但若是換種思惟考慮:是哪一個元素要添加何種事件?這個事件是怎樣的?就比如如何將大象裝進冰箱,首先打開冰箱門,把大象裝進去,關閉冰箱門;若是是一萬頭大象呢,是否是要開關一萬次?這時要是大象來了冰箱門能自動開關就行了。因此,換種思惟重寫代碼:html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
function ChangeStyle(divId,btnId){
//構造函數中this是誰?就是實例化對象cs
this.div = document.getElementById(divId);
this.btn = document.getElementById(btnId);
}
ChangeStyle.prototype.init = function(){
//原型方法裏面this指向誰?就是具體的某個經過構造函數實例化的對象cs
var _this = this
this.btn.onclick = function(){
// 這個功能加到change方法裏面,怎麼辦?
// this.style.backgroundColor = 'orange';
_this.change(this);
//假設這裏的代碼比價複雜,代碼量比較大
}
}
ChangeStyle.prototype.change = function(obj){
//這裏能獲得按鈕嗎?
// this.btn.style.backgroundColor = 'orange';
obj.style.backgroundColor = 'pink';
this.div.style.width = '300px';
this.div.style.height = '300px';
this.div.style.border = '1px yellow solid';
this.div.style.backgroundColor = 'green';
} 
//...............
var cs = new ChangeStyle('div1','btn');
cs.init();
}
</script>
</head>
<body>
<div style="width: 200px;height: 200px;border:1px solid red;" id="div1"></div>
<input type="button" value="點擊" id="btn">
</body>
</html>

 


雖然就單一功能來說,看似代碼量要複雜一些,可是未來拓展功能,不少代碼是能夠複用的。相對於面向過程編程來說,面向對象的在必定程度上避免了變量命名衝突,並且複用性強。
2、對象java

所謂對象就是某種事物;JavaScript對象的實質是無序鍵值對的集合。產生對象的方式有兩種:字面量和構造函數。
2.1字面量
經過各類數據類型的字面量表示:編程

var num = 12; var num = 1.2;

var str = 'hello'; var flag = true; 
var arr = [1,2,3]; var reg = /\d+/; 
var obj = {};

//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
var person = {}; 
person.name = '胡琦'; 
person.age = 18; 
person.sex = '男';

 

這裏的數據類型能夠是基本類型和引用類型。
2.2構造函數
內置對象和自定義對象;app

var arr = new Array(); 
var obj = new Object();

var Obj = new RegExp('\d+');
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
function Person(name,age){

this.name = name;
this.age = age; 
This.doing = function(){

console.log(this.name + ':擼碼');

}

}

var p1 = new Person('胡琦',18);

 

3、函數
JavaScript中函數的三種角色:普通函數,做爲構造函數,做爲對象;函數

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script type='text/javascript'>
//3.1普通函數


function foo(){ 'use strict'

console.log(this);

}

foo();//ES3中,this就是window;ES5的嚴格模式下,this爲undefined


3.2對象方法


var obj = {}; obj.info = 'hello';

obj.showInfo = function(){ console.log(this.info);

}

foo.showInfo();//對象方法中的this就是調用方法的對象


//3.3構造函數


function Foo(info){ this.info = info;

this.showInfo = function(){ console.log(this.info);

}

}

Foo.prototype.fn = function(){ //原型對象中的this就是實例對象 console.log(this.info);

}

var foo = new Foo('hello'); foo.showInfo();//對象方法中的this就是實例對象


call/apply/bind
function foo(a,b){ console.log(a + b);

}

foo.call(null,1,2);

foo.apply(null,[1,2]); //改變this指向 var obj1 = {

info : 'Tom'

};

var obj2 = {

info : 'Jerry'

}

window.info = 'Spike';

var    showInfo = function(){ console.log(this.info);

};

showInfo();

showInfo.call(obj1);

showInfo.call(obj2);

//調用call或apply都會自動執行對應的函數,而bind不會執行對應的函數,只是返回了對函數的引用。


//高階函數

//函數做爲參數


function foo(fn) { var data = {

info: 'hello'

}

fn(data);

}

var    fn = function(data) { console.log(data.info);

};

foo(fn);


//函數做爲返回值


function foo(){ var num = 1;

return function(){ return num++;

}

}

var fn = foo(); var r1 = fn(); var r2 = fn();

console.log(r1,r2);
 </script>
</head>
<body>

</body>
</html>

 

4、構造函數、實例對象、原型this

4.1構造函數、原型與實例的關係spa

1.每一個構造函數都有一個原型對象prototypeprototype

2.原型對象包含一個指向構造函數的指針constructor指針

3.原型對象都包含一個指向構造函數的內部指針__proto__


4.1.1 _proto__

在函數裏有一個屬性prototype
由該函數建立的對象默認會鏈接到該屬性上
4.1.2 prototype與__proto__的關係

__proto__是站在對象角度來講的
prototype是站在構造函數角度說的

4.2原型鏈


原型鏈是一個由對象組成的有限對象鏈,用於實現繼承和共享屬性。

var obj = new Object();

對象是有原型對象的,原型對象也有原型對象
obj.__proto__.__proto__.__proto__

原型對象也有原型對象,對象的原型對象一直往上找,會找到一個null var arr = [];
arr -> Array.prototype -> Object.prototype -> null var o = new Object();
o -> Object.prototype -> null

 

function Foo1(){ this.name1 = '1';

}

function Foo2(){ this.name2 = '2';

}
Foo2.prototype = new Foo1(); function Foo3(){

this.name3 = '3';

}

Foo3.prototype = new Foo2(); var foo3 = new Foo3(); console.dir(foo3);

 

 

原型鏈:實例與原型的鏈條

 

foo3 -> foo2 -> foo1 -> Foo1.prototype -> Object.prototype -> null

 

原型鏈示例

var arr = [];

1.arr ‐> Array.prototype ‐> Object.prototype ‐> null var obj = {};
2.obj ‐> Object.prototype ‐> null

構造函數、實例對象、原型對象之間額關係:

 總結:

相關文章
相關標籤/搜索