亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

JavaScript極簡入門教程(二):對象和函數

2024-05-06 16:10:04
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了JavaScript極簡入門教程(二):對象和函數,本文講解了對象基礎知識、函數基礎知識、函數調用、異常、繼承等內容,需要的朋友可以參考下
 
 

閱讀本文需要有其他語言的編程經驗。

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: add]

 

關鍵字 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<arguments.length; ++i) {
        sum += arguments[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: 'TypeError',
            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 < 0 ? 'ceil' : 'floor'](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 < n; i += 1) {
        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 < n; i += 1) {
            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 = function(name) {
    var that = this, method = that[name];
    return function() {
        return method.apply(that, arguments);
    };
};
 
var coolcat = function (spec) {
    // 獲取子類的 get_name 方法
    var that = cat(spec), super_get_name = that.superior('get_name');
    that.get_name = function(n) {
        return 'like ' + super_get_name() + ' baby';
    };
    return that;
};
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
福利视频导航一区| 国产亚洲一区二区在线| 91最新在线免费观看| 国产小视频国产精品| 激情亚洲一区二区三区四区| 中文字幕日韩视频| 日本欧美在线视频| 亚洲无线码在线一区观看| 亚洲第一网站免费视频| 欧美日韩性视频在线| 欧美有码在线观看| 精品久久久久久久大神国产| 国产精品免费一区二区三区都可以| 91久热免费在线视频| 久久av红桃一区二区小说| 久久91亚洲精品中文字幕| 欧美日韩亚洲视频一区| 91国内精品久久| 4444欧美成人kkkk| 久久久久久亚洲精品中文字幕| 国产精品十八以下禁看| 91牛牛免费视频| 91精品国产自产在线观看永久| 国内外成人免费激情在线视频网站| 欧美主播福利视频| 91夜夜揉人人捏人人添红杏| 日韩高清免费观看| 国产一区二区三区免费视频| 国产一区二区美女视频| 精品视频在线导航| www国产精品视频| 成人在线免费观看视视频| 日韩在线视频观看| 国产综合香蕉五月婷在线| 亚洲国产美女精品久久久久∴| 国产精品一区二区在线| 国产自产女人91一区在线观看| 亚洲欧美日韩在线一区| 欧美精品在线免费观看| 成人黄色激情网| 国产精品久久久亚洲| 国产精品情侣自拍| 成人日韩av在线| 国产精品国模在线| 色先锋资源久久综合5566| 国产美女精品视频免费观看| 国产精品免费视频xxxx| 欧美专区福利在线| 欧美中文在线免费| 成人国产精品免费视频| 欧美在线精品免播放器视频| 久久人人爽亚洲精品天堂| 亚洲国语精品自产拍在线观看| 国内外成人免费激情在线视频网站| 亚洲国产精彩中文乱码av在线播放| 欧美中文字幕视频在线观看| 亚洲大胆人体视频| 久久久亚洲精选| 韩国19禁主播vip福利视频| 在线电影欧美日韩一区二区私密| 欧美日韩在线免费观看| 日韩久久免费视频| 成人福利视频在线观看| 精品久久久中文| 午夜精品一区二区三区视频免费看| 午夜精品福利在线观看| 日韩二区三区在线| 国产日韩换脸av一区在线观看| 亚洲一品av免费观看| 国产91精品网站| 亚洲精品国产精品国自产在线| 国产欧美精品一区二区| 日本精品视频在线观看| 国产一区二区在线免费| 爱福利视频一区| 欧美日韩视频在线| 欧美一级片久久久久久久| 亚洲成色999久久网站| 日韩av免费网站| 久久色免费在线视频| 国产精品美女久久久久久免费| 久久久久一本一区二区青青蜜月| 97精品在线观看| 国产有码在线一区二区视频| 日韩成人在线播放| 国产日产欧美精品| 精品国产一区二区三区久久久| 中文字幕日韩专区| 91精品国产91久久久久久不卡| 欧美性生交大片免网| 国产欧美一区二区三区久久人妖| 日本午夜精品理论片a级appf发布| 尤物精品国产第一福利三区| 色综合五月天导航| 国自在线精品视频| 中文字幕亚洲自拍| 最近2019年手机中文字幕| 欧美在线观看一区二区三区| 日韩av影视综合网| 亚洲国产精彩中文乱码av在线播放| 国产精品999999| 在线观看国产精品淫| 欧美高清不卡在线| 亚洲人成网站777色婷婷| 国产精品久久久久久久久久久不卡| www.久久草.com| 久久99精品国产99久久6尤物| 中文字幕自拍vr一区二区三区| 亚洲无线码在线一区观看| 精品久久久久久久久中文字幕| 最近2019中文字幕在线高清| 久久精品免费电影| 国产精品一区电影| 国产午夜精品全部视频在线播放| 亚洲人成电影在线| 亚洲精品在线91| 欧美野外wwwxxx| 精品国产一区二区三区久久狼黑人| 日本一区二三区好的精华液| 久久久久久亚洲精品中文字幕| 日韩小视频网址| 国产精品久久久久久久久影视| 国产综合久久久久久| 欧美午夜电影在线| 久久手机免费视频| 国产精品视频内| 久久精品欧美视频| 亚洲自拍在线观看| 亚洲精品日韩久久久| 欧美日韩国产中文精品字幕自在自线| 一本色道久久综合狠狠躁篇的优点| 最近2019年好看中文字幕视频| 亚洲理论在线a中文字幕| 久久亚洲影音av资源网| 国产91色在线播放| 欧美激情视频网站| 久久久噜噜噜久久久| 亚洲激情中文字幕| 欧美黑人一级爽快片淫片高清| 国产精品91久久久| 欧美成人午夜影院| 久久人人爽人人爽爽久久| 久久天天躁狠狠躁夜夜av| 日韩av电影中文字幕| 精品精品国产国产自在线| 成人看片人aa| 国产成人精品久久亚洲高清不卡| 欧美在线一级va免费观看| 欧美精品中文字幕一区| 久久露脸国产精品| 性欧美在线看片a免费观看| 欧美大尺度在线观看| 日韩欧美在线字幕| 亚洲人午夜色婷婷| 国产专区欧美专区| 国产精品成av人在线视午夜片| 欧美与黑人午夜性猛交久久久| 国产精品99免视看9| 色av中文字幕一区| 国产专区欧美专区| 欧美另类高清videos| 国内精品久久久久久| 精品久久香蕉国产线看观看亚洲| 欧美在线视频播放|