閱讀本文需有其他語言的程式設計經驗。
JavaScript 中的簡單型別包括:
1.數字
2.字串
3.布爾(true 和 false)
4.null
5.undefined
此外的其他類型皆是物件(我們不要被 typeof 運算子的回傳值所迷惑),例如:
1.函數
2.數組
3.正規表示式
4.對象(對象自然也是對象)
物件基礎
在 JavaScript 中,物件是屬性的集合(物件為關聯陣列),每個屬性都包括:
1.屬性名,必須為字串
2.屬性值,可以為除了 undefined 之外的任何值
透過物件 literal 建立物件:
// 透過物件 literal {} 建立空物件
var empty_object = {};
物件的屬性名稱和屬性值:
var stooge = {
// "first-name" 為屬性名,"Jerome" 為屬性值
"first-name": "Jerome",
// "last-name" 為屬性名,"Howard" 為屬性值
"last-name": "Howard"
};
如果屬性名稱是合法的標識符,那麼可以省略引號:
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
我們來看屬性存取的範例:
var owner = { name: "Name5566" };
owner.name; // "Name5566"
owner["name"]; // "Name5566"
owner.job; // undefined
owner.job = "coder"; // 或 owner["job"] = "coder";
如果屬性名不是合法標識符,那麼就需要用引號包裹。不存在的屬性值為 undefined。物件是透過引用而非按值傳遞:
var x = {};
var owner = x;
owner.name = "Name5566";
x.name; // x.name === "Name5566"
這裡 x 和 owner 引用同一個物件。
物件的屬性可以使用 delete 運算子刪除:
delete obj.x; // 刪除物件 obj 的 x 屬性
物件的原型(prototype)
每一個物件都被連結了一個原型物件(prototype object),物件能夠從原型物件繼承屬性。我們透過物件 literal 建立一個對象,它的原型物件為 Object.prototype 物件(Object.prototype 物件本身沒有原型物件)。我們在創建物件的時候,可以設定物件的原型物件(之後再討論具體的設定方法)。在嘗試取得(而非修改)物件的某個屬性時,如果該物件不存在此屬性,那麼JavaScript 會嘗試從此物件的原型物件中取得此屬性,如果原型物件中沒有該屬性,那麼再從此原型對象的原型物件中查找,以此類推,直到Object.prototype 原型物件。相較於獲取屬性而言,我們修改物件的某個屬性時,不會影響原型物件。
函數基礎
在 JavaScript 中函數也是對象,其連結到 Function.prototype 原型對象(Function.prototype 連結到 Object.prototype)。函數存在一個名為 prototype 的屬性,其值的類型為對象,此物件存在一個屬性 constructor,constructor 的值為此函數:
var f = function() {}
typeof f.prototype; // 'object'
typeof f.prototype.constructor; // 'function'
f === f.prototype.constructor; // true
函數是對象,你可以像使用對像一樣使用函數,也就是說,函數可以保存在變數、陣列中,可以作為參數傳遞給函數,函數內部可以定義函數。附帶提及一下,函數有兩個被隱藏的屬性:
1.函數的上下文
2.函數的程式碼
函數的建立如下:
var f = function add(a, b) {
return a b;
}
console.log(f); // 輸出 [Function: 加]
關鍵字 function 後的函數名稱是可選的,我們制定函數名稱主要出於幾個目的:
1.為了遞歸呼叫
2.被調試器、開發工具等用來識別函數
很多時候我們並不需要函數名,沒有函數名的函數被叫做匿名函數。有括號包裹的為參數清單。 JavaScript 不要求實參和形參匹配,例如:
var add = function(a, b) {
return a b;
}
add(1, 2, 3); // 實參和形參不符
如果實參過多,那麼多餘的實參會被忽略,如果實參過少,那麼未被賦值的形參的值為 undefined。函數一定有一個回傳值,如果沒有透過 return 語句指定回傳值,那麼函數傳回值為 undefined。
一個函數和其存取的外部變數組成一個閉包。這就是 JavaScript 的關鍵魅力。
函數呼叫
每個函數被呼叫時,會接收到兩個額外的參數:
1.this
2.arguments
this 的值和具體呼叫的模式有關,在 JavaScript 中有四種呼叫模式:
1.方法呼叫模式。物件的屬性如果是函數,則稱為方法。如果一個方法透過 o.m(args) 被調用,this 為物件 o(由此可見,在調用時,this 和 o 才進行綁定),例如:
var obj = {
value: 0,
increment: function(v) {
this.value = (typeof v === 'number' ? v : 1);
}
};
obj.increment(); // this === obj
2.函數呼叫模式。如果一個函數不是一個物件的屬性,那麼它將作為一個函數被調用,這時候 this 被綁定到全域物件上,例如:
message = 'Hello World';
var p = function() {
console.log(this.message);
}
p(); // 輸出 'Hello World'
這種行為有時候讓人疑惑,看一個例子:
obj = {
value: 0,
increment: function() {
var helper = function() {
// 對全域物件中的 value 加上 1
this.value = 1;
}
// helper 被當作一個函數來呼叫
// 因此 this 為全域物件
helper();
}
};
obj.increment(); // obj.value === 0
我們預期的結果應該是:
obj = {
value: 0,
increment: function() {
var that = this;
var helper = function() {
that.value = 1;
}
helper();
}
};
obj.increment(); // obj.value === 1
3.建構函式呼叫模式。意圖使用 new 前綴的函數稱為建構函數,例如:
// Test 被叫做建構子
var Test = function(string) {
this.message = string;
}
var myTest = new Test("Hello World");
一個函數前面可以加上 new 來呼叫(這樣的函數通常大寫開頭),加上 new 之後將建立一個連結到此函數的 prototype 屬性的對象,且建構函式中 this 為此對象。
4.apply 呼叫模式。函數的 apply 方法被用來呼叫函數,其有兩個參數,第一個為 this,第二個為參數數組,例如:
var add = function(a, b) {
return a b;
}
var ret = add.apply(null, [3, 4]); // ret === 7
函數呼叫時,我們能夠存取一個名為 arguments 的類別數組(非真正的 JavaScript 數組),其包含了所有的實參,這樣我們就能實現變長參數:
var add = function() {
var sum = 0;
for (var i=0; i
}
return sum;
}
add(1, 2, 3, 4);
異常
現在來說說 JavaScript 的異常處理機制。我們使用 throw 語句來拋出異常,try-cache 語句來捕捉並處理異常:
var add = function (a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
// 拋出異常
throw {
name: '類型Error',
message: 'add needs numbers'
};
}
return a b;
}
// 捕捉並處理異常
try {
add("seven");
// e 為拋出的異常物件
} catch (e) {
console.log(e.name ': ' e.message);
}
為JavaScript 類型新增屬性
JavaScript 中大多數型別存在建構子:
1.物件的建構子為 Object
2.數組的建構子為 Array
3.函數的建構子為 Function
4.字串的建構子為 String
5.數字的建構子為 Number
6.布林的建構子為 Boolean
7.正規表示式的建構子為 RegExp
我們可以為建構函式的 prototype 新增屬性(常加法),使得此屬性對相關變數可用:
Number.prototype.integer = function() {
return Math[this }
(1.1).integer(); // 1
作用域
JavaScript 需要透過函數來建構作用域:
function() {
// ...
}();
這裡建立並執行了一個匿名函數。透過作用域能夠隱藏不希望暴露的變數:
var obj = function() {
// 隱藏 value,外部無法存取
var value = 0;
return {
// 僅此方法可以修改 value
increment: function() {
value = 1;
},
// 僅此方法可讀取 value
getValue: function() {
return value;
}
};
}();
obj.increment();
obj.getValue() === 1;
繼承
JavaScript 實作繼承的方式很多。
在創建對象時,我們可以設定對象關聯的原型對象,我們這樣做:
// 建立一個物件 o,其原型物件為 {x:1, y:2}
var o = Object.create({x:1, y:2});
Object.create 方法被定義在 ECMAScript 5 中,如果你使用 ECMAScript 3 時可以自己實作一個 create 方法:
// 如果未定義 Object.create 方法
if (typeof Object.create !== 'function') {
// 建立 Object.create 方法
Object.create = function (o) {
var F = function () {};
F.prototype = o;
// 建立一個新對象,此對象的原型對象為 o
return new F();
};
}
透過 Object.create 方法我們進行基於原型繼承:一個新物件直接繼承一個舊物件的屬性(相對於基於類別的繼承,這裡無需類別的存在,物件直接繼承物件)。範例:
var myMammal = {
name: 'Herb the Mammal',
get_name: function() {
return this.name;
},
says: function() {
return this.saying || '';
}
};
// 繼承 myMammal
var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function(n) {
var i, s = '';
for (i = 0; i if (s) {
s = '-';
}
s = 'r';
}
return s;
};
myCat.get_name = function() {
return this.says() ' ' this.name ' ' this.says();
};
上面的程式碼很簡單,但沒辦法保護私有成員。我們可以使用模組模式。在模組模式中,某一類物件由一個函數產生,並利用函數作用域保護私有成員不被外部存取:
// mammal 函數,用於建構 mammal 物件
var mammal = function(spec) {
// that 為構造的物件
var that = {};
// 公有方法 get_name 可外部存取
that.get_name = function() {
// spec.name 外在無法直接存取
return spec.name;
};
// 公有方法 says 外部存取
that.says = function() {
// spec.saying 外在無法直接存取
return spec.saying || '';
};
return that;
};
// 建立 mammal 物件
var myMammal = mammal({name: 'Herb'});
// cat 函數,用於建構 cat 物件
var cat = function(spec) {
spec.saying = spec.saying || 'meow';
// cat 繼承自 mammal,因此先建構出 mammal 物件
var that = mammal(spec);
// 加入公有方法 purr
that.purr = function(n) {
var i, s = '';
for (i = 0; i if (s) {
s = '-';
}
s = 'r';
}
return s;
};
// 修改公有方法 get_name
that.get_name = function() {
return that.says() ' ' spec.name
' ' that.says();
return that;
};
};
// 建立 cat 物件
var myCat = cat({name: 'Henrietta'});
在模組模式中,繼承是透過呼叫建構子來實現的。另外,我們也可以在子類別中存取父類別的方法:
Object.prototype.superior = 函數(名稱) {
var that = this, method = that[名稱];
回傳函數() {
return method.apply(that,arguments);
};
};
var Coolcat = 函數(規格){
// 取得子類別的 get_name 方法
var that = cat(spec), super_get_name = that.superior('get_name');
that.get_name = function(n) {
return 'like ' super_get_name() 'baby';
};
返回;
};

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中