javascript Function()
javascript Function()
JavaScript中的Function物件是函式,函式的用途分為3類:
作為普通邏輯程式碼容器;
作為物件方法;
作為建構函式。
1.作為普通邏輯程式碼容器
function multiply(x, y) {
return x * y;
}
函式multiply封裝了兩位數的乘法運算公式:
var product = multiply(128, 128); // product = 16384
建立函式例項的方式有3種。第一種是宣告式,即像宣告變數一樣,將通過function(){}識別符號建立的匿名函式直接賦值給變數,以該變數作為呼叫時的函式名稱:
var multiply = function(x, y) {
return x * y;
}
第二種是定義式,即以function關鍵字後跟函式名稱及(){}來直接定義命名函式,前面第一個multiply函式就是通過定義式建立的。
第三種是建構函式式,即通過new運算子呼叫建構函式Function來建立函式。這種方式極不常用,因此就不作介紹了。
在建立函式的3種方式中,宣告式和定義式還存在細微的差別。比如下列程式碼中的函式採用宣告式:
var example = function(){
return 1;
}
example();
var example = function(){
return 2;
}
example();
執行結果如下:
1
2
而如果採用定義式,即:
function example() {
return 1;
}
example();
function example() {
return 2;
}
example();
那麼會得到另一種結果:
2
2
即,在採用定義式建立同名函式時,後建立的函式會覆蓋先建立的函式。這種差別是由於JavaScript解釋引擎的工作機制所導致的。 JavaScript解釋引擎在執行任何函式呼叫之前,首先會在全域性作用域中註冊以定義式建立的函式,然後再依次執行函式呼叫。由於註冊函式時,後定義的函式重寫了先定義的函式,因此無論呼叫語句位於何處,執行的都是後定義的函式。相反,對於宣告式建立的函式,JavaScript解釋引擎會像對待任何宣告的變數一樣,等到執行呼叫該變數的程式碼時才會對變數求值。由於JavaScript程式碼是從上到下順序執行的,因此當執行第一個example()呼叫時,example函式的程式碼就是首先定義程式碼;而當執行第二個example()呼叫時,example函式的程式碼又變成了後來定義的程式碼。
2.作為物件方法
JavaScript在解析程式碼時,會為宣告或定義的函式指定呼叫物件。所謂呼叫物件,就是函式的執行環境。如果函式體內有以關鍵字this宣告的變數,則this引用的就是呼叫物件。
事實上,在普通的函式中,也存在呼叫物件,只不過這個呼叫物件是預設的全域性window物件而已。例如:
var product = window.multiply(128, 128); // product = 16384
這說明,預設情況下,在全域性作用域中定義或宣告的函式的呼叫物件就是window。
在物件導向程式設計中,通常將作為物件成員的函式稱為方法。例如:
var dog = {};
dog.name = "heibao";
dog.age = "3 months";
dog.shout = function() {
return "Hello, My name is" + this.name + "and I am" + this.age + "old!";
}
dog.shout(); // “Hello, My name is heibao and I am 3 months old!”
有意思的是,物件也可以借用其他物件的方法:
var cat = {};
cat.name = "xiaohua";
cat.age = "2 years";
cat.greet = dog.shout;
cat.greet(); //“Hello, My name is xiaohua and I am 2 years old!”
另外,使用函式物件的call和apply方法,還可以動態指定函式或方法的呼叫物件:
dog.shout.call(cat); //“Hello, My name is xiaohua and I am 2 years old!”
或者
dog.shout.apply(cat); //“Hello, My name is xiaohua and I am 2 years old!”
3.作為建構函式
JavaScript是通過建構函式來模擬面嚮物件語言中的類的。例如:
function Animal(sort, character) {
this.sort = sort;
this.character = character;
}
以Animal作為建構函式,就可以像下面這樣建立一個新物件:
var dog = new Animal("mammal", "four legs");
建立dog的物件的過程如下:首先,new運算子建立一個空物件({}),然後以這個空物件為呼叫物件呼叫函式Animal,為這個空物件新增兩個屬性sort和character,接著,再將這個空物件的預設constructor屬性修改為建構函式的名稱(即Animal;空物件建立時預設的 constructor屬性值是Object),並且將空物件的__proto__屬性設定為指向Animal.prototype——這就是所謂的物件初始化。最後,返回初始化完畢的物件。這裡將返回的新物件賦值給了變數dog。
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Animal
聰明的讀者結合前面介紹的內容,可能會認為使用new運算子呼叫建構函式建立物件的過程也可以像下面這樣來實現:
var dog = {};
Animal.call(dog, "mammal", "four legs");
表面上看,這兩行程式碼與var dog = new Animal("mammal", "four legs");是等價的,其實卻不是。雖然通過指定函式的執行環境能夠部分達到初始化物件的目的,例如空物件dog確實獲得了sort和character這兩個屬性:
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Object —— 注意,沒有修改dog物件預設的constructor屬性
但是,最關鍵的是新建立的dog物件失去了通過Animal.prototype屬性繼承其他物件的能力。只要與前面採用new運算子呼叫建構函式建立物件的過程對比一下,就會發現,new運算子在初始化新物件期間,除了為新物件新增顯式宣告的屬性外,還會對新物件進行了一番“暗箱操作”——即將新物件的constructor屬性重寫為Animal,將新物件的__proto__屬性設定為指向Animal.prototype。雖然手工“初始化物件”也可以將dog.constructor重寫為Animal,但根據ECMA262規範,物件的__proto__屬性對開發人員是隻讀的,對它的設定只能在通過new運算子建立物件時由JavaScript解釋引擎替我們完成。
JavaScript是基於原型繼承的,如果不能正確設定物件的__proto__屬性,那麼就意味著預設的繼承機制會失效:
Animal.prototype.greet = "Hi, good lucky!";
dog.greet; // undefined
事實上,在Firefox中,__proto__屬性也是可寫的:
Animal.prototype.greet = "Hi, good lucky!";
dog.__proto__ = Animal.prototype;
dog.greet; // Hi, good lucky!
但這樣做只能在Firefox中行得通。考慮到在相容多瀏覽器,必須依賴於new運算子,才能實現基於原型的繼承
作為普通邏輯程式碼容器;
作為物件方法;
作為建構函式。
1.作為普通邏輯程式碼容器
function multiply(x, y) {
return x * y;
}
函式multiply封裝了兩位數的乘法運算公式:
var product = multiply(128, 128); // product = 16384
建立函式例項的方式有3種。第一種是宣告式,即像宣告變數一樣,將通過function(){}識別符號建立的匿名函式直接賦值給變數,以該變數作為呼叫時的函式名稱:
var multiply = function(x, y) {
return x * y;
}
第二種是定義式,即以function關鍵字後跟函式名稱及(){}來直接定義命名函式,前面第一個multiply函式就是通過定義式建立的。
第三種是建構函式式,即通過new運算子呼叫建構函式Function來建立函式。這種方式極不常用,因此就不作介紹了。
在建立函式的3種方式中,宣告式和定義式還存在細微的差別。比如下列程式碼中的函式採用宣告式:
var example = function(){
return 1;
}
example();
var example = function(){
return 2;
}
example();
執行結果如下:
1
2
而如果採用定義式,即:
function example() {
return 1;
}
example();
function example() {
return 2;
}
example();
那麼會得到另一種結果:
2
2
即,在採用定義式建立同名函式時,後建立的函式會覆蓋先建立的函式。這種差別是由於JavaScript解釋引擎的工作機制所導致的。 JavaScript解釋引擎在執行任何函式呼叫之前,首先會在全域性作用域中註冊以定義式建立的函式,然後再依次執行函式呼叫。由於註冊函式時,後定義的函式重寫了先定義的函式,因此無論呼叫語句位於何處,執行的都是後定義的函式。相反,對於宣告式建立的函式,JavaScript解釋引擎會像對待任何宣告的變數一樣,等到執行呼叫該變數的程式碼時才會對變數求值。由於JavaScript程式碼是從上到下順序執行的,因此當執行第一個example()呼叫時,example函式的程式碼就是首先定義程式碼;而當執行第二個example()呼叫時,example函式的程式碼又變成了後來定義的程式碼。
2.作為物件方法
JavaScript在解析程式碼時,會為宣告或定義的函式指定呼叫物件。所謂呼叫物件,就是函式的執行環境。如果函式體內有以關鍵字this宣告的變數,則this引用的就是呼叫物件。
事實上,在普通的函式中,也存在呼叫物件,只不過這個呼叫物件是預設的全域性window物件而已。例如:
var product = window.multiply(128, 128); // product = 16384
這說明,預設情況下,在全域性作用域中定義或宣告的函式的呼叫物件就是window。
在物件導向程式設計中,通常將作為物件成員的函式稱為方法。例如:
var dog = {};
dog.name = "heibao";
dog.age = "3 months";
dog.shout = function() {
return "Hello, My name is" + this.name + "and I am" + this.age + "old!";
}
dog.shout(); // “Hello, My name is heibao and I am 3 months old!”
有意思的是,物件也可以借用其他物件的方法:
var cat = {};
cat.name = "xiaohua";
cat.age = "2 years";
cat.greet = dog.shout;
cat.greet(); //“Hello, My name is xiaohua and I am 2 years old!”
另外,使用函式物件的call和apply方法,還可以動態指定函式或方法的呼叫物件:
dog.shout.call(cat); //“Hello, My name is xiaohua and I am 2 years old!”
或者
dog.shout.apply(cat); //“Hello, My name is xiaohua and I am 2 years old!”
3.作為建構函式
JavaScript是通過建構函式來模擬面嚮物件語言中的類的。例如:
function Animal(sort, character) {
this.sort = sort;
this.character = character;
}
以Animal作為建構函式,就可以像下面這樣建立一個新物件:
var dog = new Animal("mammal", "four legs");
建立dog的物件的過程如下:首先,new運算子建立一個空物件({}),然後以這個空物件為呼叫物件呼叫函式Animal,為這個空物件新增兩個屬性sort和character,接著,再將這個空物件的預設constructor屬性修改為建構函式的名稱(即Animal;空物件建立時預設的 constructor屬性值是Object),並且將空物件的__proto__屬性設定為指向Animal.prototype——這就是所謂的物件初始化。最後,返回初始化完畢的物件。這裡將返回的新物件賦值給了變數dog。
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Animal
聰明的讀者結合前面介紹的內容,可能會認為使用new運算子呼叫建構函式建立物件的過程也可以像下面這樣來實現:
var dog = {};
Animal.call(dog, "mammal", "four legs");
表面上看,這兩行程式碼與var dog = new Animal("mammal", "four legs");是等價的,其實卻不是。雖然通過指定函式的執行環境能夠部分達到初始化物件的目的,例如空物件dog確實獲得了sort和character這兩個屬性:
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Object —— 注意,沒有修改dog物件預設的constructor屬性
但是,最關鍵的是新建立的dog物件失去了通過Animal.prototype屬性繼承其他物件的能力。只要與前面採用new運算子呼叫建構函式建立物件的過程對比一下,就會發現,new運算子在初始化新物件期間,除了為新物件新增顯式宣告的屬性外,還會對新物件進行了一番“暗箱操作”——即將新物件的constructor屬性重寫為Animal,將新物件的__proto__屬性設定為指向Animal.prototype。雖然手工“初始化物件”也可以將dog.constructor重寫為Animal,但根據ECMA262規範,物件的__proto__屬性對開發人員是隻讀的,對它的設定只能在通過new運算子建立物件時由JavaScript解釋引擎替我們完成。
JavaScript是基於原型繼承的,如果不能正確設定物件的__proto__屬性,那麼就意味著預設的繼承機制會失效:
Animal.prototype.greet = "Hi, good lucky!";
dog.greet; // undefined
事實上,在Firefox中,__proto__屬性也是可寫的:
Animal.prototype.greet = "Hi, good lucky!";
dog.__proto__ = Animal.prototype;
dog.greet; // Hi, good lucky!
但這樣做只能在Firefox中行得通。考慮到在相容多瀏覽器,必須依賴於new運算子,才能實現基於原型的繼承
相關文章
- JavaScript FunctionJavaScriptFunction
- javascript 中function(){},new function(),new Function(),Function 摘錄JavaScriptFunction
- JavaScript Function物件JavaScriptFunction物件
- JavaScript function 函式JavaScriptFunction函式
- JavaScript中的 FunctionJavaScriptFunction
- Javascript showModalDialog() FunctionJavaScriptFunction
- [Javascript] Why need arrow function?JavaScriptFunction
- Javascript 物件導向學習1 Function function ObjectJavaScript物件FunctionObject
- javascript Function()建構函式JavaScriptFunction函式
- 【JavaScript】Function型別是物件JavaScriptFunction型別物件
- JavaScript入門-函式function(二)JavaScript函式Function
- javascript Function()使用程式碼例項JavaScriptFunction
- JavaScript Function 函式深入總結JavaScriptFunction函式
- JavaScript Promise Time Limit Function All In OneJavaScriptPromiseMITFunction
- 使用原生javascript實現jquery的$(function(){ })JavaScriptjQueryFunction
- javascript function的多種用法詳解JavaScriptFunction
- 理解 JavaScript 中的 Function.prototype.bindJavaScriptFunction
- 理解JavaScript中的Function.prototype.bindJavaScriptFunction
- Javascript之旅——第九站:吐槽functionJavaScriptFunction
- 新人必看的短小而精悍的javascript functionJavaScriptFunction
- JavaScript中的Date,RegExp,Function物件JavaScriptFunction物件
- JavaScript自執行函式(function(){})()的理解JavaScript函式Function
- javascript __proto___ prototype和Function原始碼狂想JavaScriptFunction原始碼
- JavaScript 高階函式(Heigher-order function)JavaScript函式Function
- JavaScript學習總結(四)function函式部分JavaScriptFunction函式
- JavaScript中的函式過載(Function overloading)JavaScript函式Function
- javascript中的自執行(立即執行)函式(function(){…})()JavaScript函式Function
- JavaScript: window.onload = function() {} 裡面的函式不執行JavaScriptFunction函式
- js原型繼承與多型 How to apply virtual function in javascriptJS原型繼承多型APPFunctionJavaScript
- $(function(){})與(function($){....})(jQuery)的區別FunctionjQuery
- JavaScript 基礎(二) – 建立 function 物件的方法, String物件, Array物件JavaScriptFunction物件
- sendDataByUdp FunctionUDPFunction
- Substr FunctionFunction
- Function : dumpFunction
- [Bash] functionFunction
- [Javascript] Access private variable inside IIFE and mutate this through Object.prototype getter functionJavaScriptIDEObjectFunction
- JavaScript 引擎和 Just-in-Time 編譯概念,Hot Function 的簡單介紹JavaScript編譯Function
- 【JavaScript框架封裝】使用Prototype給Array,String,Function物件的方法擴充JavaScript框架封裝Function物件