4.1變量,作用域
Javascript變量是松散類型的本質,決定了它只是在特定的時間用于保存特定的值而已。由于不存在定義某個變量必須要保存何種數(shù)據(jù)類型值的規(guī)則,變量的值及其數(shù)據(jù)類型可以在腳本的生命周期內改變。
ECMAScript變量可能包含兩種不同數(shù)據(jù)類型的值:
基本類型和引用類型
基本類型就是簡單的數(shù)據(jù)段 (Undefined Null Number Boolean String )基本類型是按值訪問的
引用類型是那些可能由多個值構成的對象(Object)引用類型實際上是在操作對象的引用,而不是實際的對象
區(qū)別
1復制變量值
1)基本類型:會在變量對象上創(chuàng)建一個新值,然后把改值復制到新變量
分配的位置上 互不影響 完全獨立
2)引用類型:復制的是原來對象的指針,這個指針指向存儲在堆中的一個對象。復制操作結束后實際上兩個變量引用同一個對象。改變其一會影響另一個變量
4.1.4檢測類型
基本數(shù)據(jù)類型的檢測用typeof
引用類型的檢測用instanceof
6.2創(chuàng)建對象
1.工廠模式
function obj(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
var person1 = obj("Nike",28,"enginner")
2構造函數(shù)模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name)
}
}
var person2 = new Person("Lucy",28,"enginner");
3原型模式
function Person(){}
Person.prototype.name = "Nike";
Person.prototype.age = 28;
Person.prototype.job = "Engineer";
Person.sayName = function(){
alert(this.name);
}
4組合使用構造函數(shù)和原型
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Nike","Lucy"]
}
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}
var person1 = new Person();
var person2 = new Person();
person2.friends.push("Lili");
console.log(person2.friends)
console.log(person1.friends)
console.log(person2.friends === person1.friends)
5動態(tài)原型模式
有其他 OO 語言經驗的開發(fā)人員在看到獨立的構造函數(shù)和原型時,很可能會感到非常困惑。動態(tài)原
型模式正是致力于解決這個問題的一個方案,它把所有信息都封裝在了構造函數(shù)中,而通過在構造函數(shù)
中初始化原型(僅在必要的情況下),又保持了同時使用構造函數(shù)和原型的優(yōu)點。換句話說,可以通過
檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。來看一個例子
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
}
}
}
var fr = new Person("Bill",10,"student");
6寄生構造函數(shù)模式
function SpecialArray(){
var value = new Array();
value.push.apply(value, arguments);
value.toPipedString = function(){
return this.join("|");
}
return value;
}
var val = new SpecialArray("red","blue");
console.log(val instanceof SpecialArray)
in 操作符 和 hasOwnProperty()
有兩種方式使用 in 操作符:單獨使用和在 for-in 循環(huán)中使用。在單獨使用時,in 操作符會在通
過對象能夠訪問給定屬性時返回 true,無論該屬性存在于實例中還是原型中。
由于 in 操作符只要通過對象能夠訪問到屬性就返回 true,hasOwnProperty()只在屬性存在于
實例中時才返回 true
keys()
要取得對象上所有可枚舉的實例屬性,可以使用 ECMAScript 5 的 Object.keys()方法。這個方法
接收一個對象作為參數(shù),返回一個包含所有可枚舉屬性的字符串數(shù)組
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"
****原型的動態(tài)性****
盡管可以隨時為原型添加屬性和方法,并且修改能夠立即在所有對象實例中反映出來,但如果是重
寫整個原型對象,那么情況就不一樣了。我們知道,調用構造函數(shù)時會為實例添加一個指向最初原型的
[[Prototype]]指針,而把原型修改為另外一個對象就等于切斷了構造函數(shù)與最初原型之間的聯(lián)系。
請記住:實例中的指針僅指向原型,而不指向構造函數(shù)
function Person(){
}
var friend = new Person();
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
friend.sayName(); //error
proto
繼承是面向對象編程的最最基礎的概念,本文主要講解JS中繼承的實現(xiàn)方式及原理。
將共享方法抽象到函數(shù)prototype中。
對于共享屬性/方法,沒必要每個對象都復制一份,只需要能引用到這個屬性就可以了,而這與prototype的思路正好相同。