目錄
資料型別
原始型別
引用型別
属性类型
禁止修改对象
首頁 web前端 js教程 JavaScript 物件導向精要(一)

JavaScript 物件導向精要(一)

Mar 06, 2017 pm 02:32 PM

資料型別

在JavaScript中,資料型別分為兩類:

原始型別

儲存一些簡單數據,如true, 5等。 JavaScript共有5中原始型別:

  • boolean:布爾,值為true或false

  • number:數字,值為任何整數會浮點數

  • string:字串,值為由單引號或雙引號括出的單一字元或連續字元(JavaScript不區分字元類型)

  • null:空類型,其只有一個值:nulll

  • #undefined:未定義,其只有一個值:undefined

#
var name = "Pomy";
var blog = "http://www.ido321.com";
var age = 22;
alert(typeof blog); //"string"
alert(typeof age); //"number"
登入後複製

原始類型的值是直接保存在變數中,並且可以用typeof 進行偵測。但是typeof對null的偵測是回傳object,而不是回傳null:

//弹出Not null
if(typeof null){
    alert("Not null");   
}else{
    alert("null");
}
登入後複製

所以偵測null時,最好用全等於(===),其還能避免強制型別轉換:

console.log("21" === 21);  //false
console.log("21" == 21);  //true
console.log(undefined == null);  //true
console.log(undefined === null);  //false
登入後複製

對於字串、數字或布林值,其都有對應的方法,這些方法來自於對應的原始封裝類型:String、Number和Boolean。原始封裝類型將會自動建立。

var name = "Pomy";
var char = name.charAt(0);
console.log(char);  //"P"
登入後複製

在JavaScript引擎中發生的事情:

var name = "Pomy";
var temp = new String(name);
var char = temp.charAt(0);
temp = null;
console.log(char);  //"P"
登入後複製

字串物件的引用在用完之後立即被銷毀,所以不能給字串添加屬性,並且instanceof檢測對應類型時均回傳false:

var name = "Pomy";
name.age = 21;
console.log(name.age);   //undefined
console.log(name instanceof String);  //false
登入後複製

引用型別

儲存為對象,實質是指向記憶體位置的引用,所以不在變數中儲存物件。除了自訂的對象,JavaScript提供了6中內建類型:

  • Array:數組類型,以數字為索引的一組值的有序列表

  • Date:日期和時間類型

  • ##Error:運行期間錯誤類型

  • Function:函數類型

  • Object:通用物件類型

  • RegExp:正規表示式類型

可以用new來實例化每一個對象,或用字面量形式來建立對象:

var obj = new Object;
var own = {
            name:"Pomy",
            blog:"http://www.ido321.com",
            "my age":22
        };
console.log(own.blog);    //访问属性
console.log(own["my age"]); 
obj = null;  //解除引用
登入後複製

obj 並不包含對象實例,而是一個指向記憶體中實際對象所在位置的指標(或者說引用)。因為typeof對所有非函數的參考型別均傳回object,所以需要用instanceof來偵測引用型別。

函數

在JavaScript中,函數就是物件。使函數不同於其他物件的決定性特性是函數存在一個被稱為[[Call]]的內部屬性。內部屬性無法透過程式碼存取而是定義了程式碼執行時的行為。

建立形式

1、函數宣告:用function關鍵字,會被提升到上下文

2、函數表達式:不能被提升
3、實例化Function內建置類型

sayHi();    //函数提升
function sayHi(){
    console.log("Hello");
}
//其他等效等效方式
/*
var sayHi = function(){
     console.log("Hello");
}
var sayHi = new Function(" console.log(\"Hello\");");
*/
登入後複製

參數

JavaScript函數的另一個獨特之處在於可以給函數傳遞任意數量的參數。函數參數被保存在arguments類別數組物件中,其自動存在函數中,能透過數字索引來引用參數,但它不是數組實例:

alert(Array.isArray(arguments));   //false
登入後複製

類別數組物件arguments 保存的是函數的實參,但並不會忽略形參。因而,arguments.length返回實參列表的長度,arguments.callee.length返回形參列表的長度。

function ref(value){
    return value;
}
console.log(ref("Hi"));
console.log(ref("Hi",22));
console.log(ref.length);  //1
登入後複製

函數中的this

關於this的問題,可參考此文:JavaScript中的this。

JavaScript提供了三個方法用來改變this的指向:call、apply和bind。三個函數的第一個參數都是指定this的值,其他參數都作為參數傳遞給函數。

物件

物件是一種參考類型,建立物件常見的兩種方式:Object建構子與物件字面量形式:

var per1 = {
    name:"Pomy",
    blog:"http://www.ido321.com"
};
var per2 = new Object;
per2.name = "不写代码的码农";
登入後複製

屬性運算

在JavaScript中,可以隨時為物件新增屬性:

per1.age = 0;
per1.sayName = function(){
    alert(this.name);   //"Pomy"
}
登入後複製

因而,在偵測物件屬性是否存在時,常犯的一個錯誤是:

//结果是false
if(per1.age){
    alert(true)
}else{
    alert(false);
}
登入後複製

per1.age 是存在的,但是其值是0,所以不能滿足if條件。 if判斷中的值是物件、非空字串、非零數字或true時,判斷會評估為真;而當值為一個null、undefined、0、false、NaN或空字串時評估為假。

因而,偵測屬性是否存在時,有另外的兩種方式:in和hasOwnProperty(),前者會偵測原型屬性和自有(實例)屬性,後者只偵測自有(實例)屬性。

console.log("age" in per1);  //true
console.log(per1.hasOwnProperty("age"));  //true
console.log("toString" in per1);  //true
console.log(per1.hasOwnProperty("toString"));  //false
登入後複製

物件per1並沒有定義toString,該屬性繼承於Object.prototype,所以in和hasOwnProperty()偵測該屬性時出現差異。如果只想判斷一個物件屬性是不是原型,可以利用以下方法:

function isPrototypeProperty(obj,name){
    return name in obj && !obj.hasOwnProperty(name);
}
登入後複製

若要刪除一個屬性,用delete操作符,用於刪除自有屬性,不能刪除原型屬性。

per1.toString = function(){
    console.log("per1对象");
};
console.log(per1.hasOwnProperty("toString"));   //true
per1.toString();   //"per1对象"
delete per1.toString;
console.log(per1.hasOwnProperty("toString"));   //false
console.log(per1.toString());  //[object Object]
登入後複製

有時需要枚舉物件的可枚舉屬性,也有兩種方式:for-in迴圈和Object.keys(),前者依舊會遍歷出原型屬性,後者只回傳自有屬性。所有可列舉屬性的內部屬性[[Enumerable]]的值均為true。

var per3 = {
    name:"Pomy",
    blog:"http://www.ido321.com",
    age:22,
    getAge:function(){
        return this.age;
    }
};
登入後複製

實際上,大部分原生屬性的[[Enumerable]]的值均為false,即該屬性不能列舉。可以透過propertyIsEnumerable()來偵測屬性是否可以列舉:

console.log(per3.propertyIsEnumerable("name"));  //true
var pros = Object.keys(per3);  //返回可枚举属性的名字数组
console.log("length" in pros);  //true
console.log(pros.propertyIsEnumerable("length"));  //false
登入後複製

属性name是自定义的,可枚举;属性length是Array.prototype的内建属性,不可枚举。

属性类型

属性有两种类型:数据属性和访问器属性。二者均具有四个属性特征:

  • 数据属性:[[Enumerable]]、[[Configurable]]、[[Value]]和[[Writable]]

  • 访问器属性:[[Enumerable]]、[[Configurable]]、[[Get]]和[[Set]]

[[Enumerable]] :布尔值,属性是否可枚举,自定义属性默认是true。
[[Configurable]] :布尔值,属性是否可配置(可修改或可删除),自定义属性默认是true。它是不可逆的,即设置成false后,再设置成true会报错。
[[Value]]:保存属性的值。
[[Writable]]:布尔值,属性是否可写,所有属性默认可写。
[[Get]]:获取属性值。
[[Set]]:设置属性值。

ES 5提供了两个方法用于设置这些内部属性:
Object.defineProperty(obj,pro,desc_map) 和 Object.defineProperties(obj,pro_map)。利用这两个方法为per3添加一个属性和创建一个新对象per4:

Object.defineProperty(per3,"sex",{
    value:"male",
    enumerable:false,
    configurable:false, //属性不能删除和修改,该值也不能被设置成true
});
console.log(per3.sex);  //'male'
console.log(per3.propertyIsEnumerable("sex"));  //false
delete per3.sex;    //不能删除
per3.sex = "female"; //不能修改
console.log(per3.sex);  //'male'
Object.defineProperty(per3,"sex",{
    configurable:true, //报错
});
per4 = {};
Object.defineProperties(per4,{
    name:{
        value:"dwqs",
        writable:true
    },
    blog:{
        value:"http://blog.92fenxiang.com"
    },
    Name:{
        get:function(){
            return this.name;
        },
        set:function(value){
            this.name = value;
        },
        enumerable:true,
        configurable:true
    }
});
console.log(per4.name); //dwqs
per4.Name = "Pomy";
console.log(per4.Name); //Pomy
登入後複製

需要注意的是,通过这两种方式来定义新属性时,如果不指定特征值,则默认是false,也不能创建同时具有数据特征和访问器特征的属性。可以通过Object.getOwnPropertyDescriptor()方法来获取属性特征的描述,接受两个参数:对象和属性名。若属性存在,则返回属性描述对象。

var desc = Object.getOwnPropertyDescriptor(per4,"name");
console.log(desc.enumerable); //false
console.log(desc.configurable); //false
console.log(desc.writable); //true
登入後複製

根据属性的属性类型,返回的属性描述对象包含其对应的四个属性特征。

禁止修改对象

对象和属性一样具有指导其行为的内部特征。其中,[[Extensible]]是一个布尔值,指明改对象本身是否可以被修改([[Extensible]]值为true)。创建的对象默认都是可以扩展的,可以随时添加新的属性。
ES5提供了三种方式:

  • Object.preventExtensions(obj):创建不可扩展的obj对象,可以利用Object.isExtensible(obj)来检测obj是否可以扩展。严格模式下给不扩展对象添加属性会报错,非严格模式下则添加失败。

  • Object.seal(obj):封印对象,此时obj的属性变成只读,不能添加、改变或删除属性(所有属性都不可配置),其[[Extensible]]值为false,[[Configurable]]值为false。可以利用Object.isSealed(obj)来检测obj是否被封印。

  • Object.freeze(obj):冻结对象,不能在冻结对象上添加或删除属性,不能改变属性类型,也不能写入任何数据类型。可以利用Object.isFrozen(obj)来检测obj是否被冻结。 注意:冻结对象和封印对象均要在严格模式下使用。

"use strict";
var per5 = {
    name:"Pomy"
};
console.log(Object.isExtensible(per5));   //true
console.log(Object.isSealed(per5));         //false
console.log(Object.isFrozen(per5));       //false
Object.freeze(per5);
console.log(Object.isExtensible(per5));   //false
console.log(Object.isSealed(per5));       //true
console.log(Object.isFrozen(per5));       //true
per5.name="dwqs";
console.log(per5.name);   //"Pomy"
per5.Hi = function(){
    console.log("Hi");
};
console.log("Hi" in per5);  //false
delete per5.name;
console.log(per5.name);  //"Pomy"
var desc = Object.getOwnPropertyDescriptor(per5,"name");
console.log(desc.configurable);  //false
console.log(desc.writable);  //false
登入後複製

注意,禁止修改对象的三个方法只对对象的自有属性有效,对原型对象的属性无效,仍然可以在原型上添加或修改属性。

function Person(name){
    this.name = name;
}
var person1 = new Person("Pomy");
var person2 = new Person("dwqs");
Object.freeze(person1);
Person.prototype.Hi = function(){
    console.log("Hi");
};
person1.Hi();  //"Hi";
person2.Hi();  //"Hi";
登入後複製

以上就是JavaScript 面向对象精要(一) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

探索Go語言中的物件導向編程 探索Go語言中的物件導向編程 Apr 04, 2024 am 10:39 AM

Go語言支援物件導向編程,透過型別定義和方法關聯實作。它不支援傳統繼承,而是透過組合實現。介面提供了類型間的一致性,允許定義抽象方法。實戰案例展示如何使用OOP管理客戶訊息,包括建立、取得、更新和刪除客戶操作。

PHP高階特性:物件導向程式設計的最佳實踐 PHP高階特性:物件導向程式設計的最佳實踐 Jun 05, 2024 pm 09:39 PM

PHP中OOP最佳實務包括命名約定、介面與抽象類別、繼承與多型、依賴注入。實戰案例包括:使用倉庫模式管理數據,使用策略模式實現排序。

Golang中有類似類別的物件導向特性嗎? Golang中有類似類別的物件導向特性嗎? Mar 19, 2024 pm 02:51 PM

在Golang(Go語言)中並沒有傳統意義上的類別的概念,但它提供了一種稱為結構體的資料類型,透過結構體可以實現類似類別的物件導向特性。在本文中,我們將介紹如何使用結構體實現物件導向的特性,並提供具體的程式碼範例。結構體的定義和使用首先,讓我們來看看結構體的定義和使用方式。在Golang中,結構體可以透過type關鍵字定義,然後在需要的地方使用。結構體中可以包含屬

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

Go語言的物件導向特性解析 Go語言的物件導向特性解析 Apr 04, 2024 am 11:18 AM

Go語言支援物件導向編程,透過struct定義對象,使用指標接收器定義方法,並透過介面實現多態。物件導向特性在Go語言中提供了程式碼重用、可維護性和封裝,但也存在缺乏傳統類別和繼承的概念以及方法簽章強制型別轉換的限制。

PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 PHP物件導向程式設計的深入理解:物件導向程式設計的除錯技巧 Jun 05, 2024 pm 08:50 PM

透過掌握追蹤物件狀態、設定斷點、追蹤異常和利用xdebug擴展,可以有效調試PHP物件導向程式碼。 1.追蹤物件狀態:使用var_dump()和print_r()檢視物件屬性和方法值。 2.設定斷點:在開發環境中設定斷點,偵錯器會在執行到達斷點時暫停,以便檢查物件狀態。 3.追蹤異常:使用try-catch區塊和getTraceAsString()取得異常發生時的堆疊追蹤和訊息。 4.利用偵錯器:xdebug_var_dump()函數可在程式碼執行過程中檢查變數的內容。

JavaScript和WebSocket:打造高效率的即時搜尋引擎 JavaScript和WebSocket:打造高效率的即時搜尋引擎 Dec 17, 2023 pm 10:13 PM

JavaScript和WebSocket:打造高效率的即時搜尋引擎引言:隨著網路的發展,使用者對即時搜尋引擎的要求也越來越高。傳統的搜尋引擎在進行搜尋時,使用者需要點擊搜尋按鈕後才能得到結果,這種方式無法滿足使用者對於即時搜尋結果的需求。因此,採用JavaScript和WebSocket技術來實現即時搜尋引擎成為了一個熱門的話題。本文將詳細介紹使用JavaScri

See all articles