成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript重溫OOP之類與對(duì)象

RancherLabs / 1081人閱讀

摘要:對(duì)構(gòu)造函數(shù)使用運(yùn)算符,就能生成實(shí)例,并且變量會(huì)綁定在實(shí)例對(duì)象上。這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)的實(shí)例繼承。

對(duì)象 對(duì)象的含義

所謂對(duì)象,就是一種無序的數(shù)據(jù)集合,由若干個(gè)“鍵值對(duì)”(key-value)構(gòu)成。

對(duì)象的創(chuàng)建

使用new運(yùn)算符創(chuàng)建Object

var p = new Object();
p.name = "Tony";    

使用對(duì)象字面量的形式

//對(duì)象字面量形式
var p ={
    name: "tony",
    work: function(){
        console.log("working....");
    },
    _age: 18,
    get age(){
        return this._age;
    },
    set age(val){
        if( val <0 || val > 150){
            throw new Error("invalid value");
        }else{
            this._age = val;
        }
    }
}
console.log(p.name);

對(duì)象的基本操作

成員屬性的添加

// Object.defineProperty()方法
Object.defineProperty(p, "age",{value: 18, writable: false});
//Object.defineProperties()方法 添加多個(gè)屬性
Object.defineProperties(p, {
    salary:{
        value: 1000,
        writable: false
    },
    gender:{
        value: true
    }
});

成員的遍歷

使用 for..in語句

Object.keys()方法 返回一個(gè)包含對(duì)象鍵名的字符串?dāng)?shù)組

var o ={};
o.name = "jack";
o.age = 20;
for(var i in o){
    console.log(o[i]);
} // jack, 20
Object.keys(o); // ["name", "age"]

檢查對(duì)象是否有某個(gè)屬性

in 操作符

Object.hasOwnProperty()方法

var o = {name: "mariya"}
"name" in o; // true
o.hasOwnProperty("name"); // true

得到對(duì)象的屬性特性描述

Object.getOwnPropertyDescriptor(obj,property)

Object.getOwnPropertyDescriptor(o, "name");
//Object {value: "mariya", writable: true, enumerable: true, configurable: true}

刪除屬性

delete運(yùn)算符,但有些對(duì)象的屬性是刪除不了的

delete o.name; //true
o.name;  // undefined 

成員特性

configurable 是否可設(shè)置

writable 是否可修改

enumerable 是否可枚舉

value屬性的值

var person ={};
Object.defineProperties(person,{
    title: {value: "fe",enumerable: true},
    age: {value: 19, enumerable: true, writable: true}
});
Object.getOwnPropertyDescriptor(person,"title");
// Object {value: "fe", writable: false, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(person,"age");
// Object {value: 19, writable: true, enumerable: true, configurable: false}
Constructor屬性

constructor始終指向創(chuàng)建當(dāng)前對(duì)象的構(gòu)造函數(shù)。

var arr = [];
console.log(arr.constructor === Array); // true
var Foo = function() {};
console.log(Foo.constructor === Function); // true
// 由構(gòu)造函數(shù)實(shí)例化一個(gè)obj對(duì)象
var obj = new Foo();
console.log(obj.constructor === Foo); // true
console.log(obj.constructor.constructor === Function); // true

每個(gè)函數(shù)都有一個(gè)默認(rèn)的屬性prototype,而這個(gè)prototypeconstructor默認(rèn)指向這個(gè)函數(shù)。

function Person(name) {
    this.name = name;
};
Person.prototype.getName = function() {
    return this.name;
};
var p = new Person("jack");
console.log(p.constructor === Person);  // true
console.log(Person.prototype.constructor === Person); // true
console.log(p.constructor.prototype.constructor === Person); // true
類的創(chuàng)建

雖然js是門基于對(duì)象的語言,但是沒有類這一概念的,雖然保留了class的關(guān)鍵字,但在ES6之前是無法使用的。所以,可以用構(gòu)造函數(shù)模擬類的創(chuàng)建,也就是偽類。

所謂"構(gòu)造函數(shù)",其實(shí)就是一個(gè)普通函數(shù),但是內(nèi)部使用了this變量。對(duì)構(gòu)造函數(shù)使用new運(yùn)算符,就能生成實(shí)例,并且this變量會(huì)綁定在實(shí)例對(duì)象上。

每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype屬性,指向另一個(gè)對(duì)象。這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)的實(shí)例繼承。

這意味著,我們可以把那些不變的屬性和方法,直接定義在prototype對(duì)象上。

//構(gòu)造函數(shù)模式
function Person(age, name){ //Class
    this.age = age;
    this.name = name;
}
//將公共的屬性或方法放在prototype屬性上
Person.prototype.headCount = 1;
//創(chuàng)建實(shí)例對(duì)象
var p = new Person(19, "johnsom");
var p1 = new Person(20, "allen");
this

this表示當(dāng)前對(duì)象,如果在全局作用范圍內(nèi)使用this,則指代當(dāng)前頁面對(duì)象window; 如果在函數(shù)中使用this,則this指代什么是根據(jù)運(yùn)行時(shí)此函數(shù)在什么對(duì)象上被調(diào)用。 我們還可以使用applycall兩個(gè)全局方法來改變函數(shù)中this的具體指向。

1. 全局代碼中的this
console.log(this === window); //true 全局范圍內(nèi)使用this指向window對(duì)象
2. 普通的函數(shù)調(diào)用
function f(){
    this.name = "tony"; // this在運(yùn)行時(shí)指向window對(duì)象,在嚴(yán)格模式下則是undefined
}
3. 在對(duì)象中使用
var o = {
    name: "tony",
    print: function(){
        console.log(this.name);  //this指向?qū)ο髈,但是可以改變其指向
    }
};
4. 作為構(gòu)造函數(shù)
new F(); // 函數(shù)內(nèi)部的this指向新創(chuàng)建的對(duì)象。
5. 多層嵌套的內(nèi)部函數(shù)
var name = "global";
var person = {
    name : "person",
    hello : function(sth){
        var sayhello = function(sth) {
            console.log(this.name + " says " + sth);
        };
        sayhello(sth);
    }
}
person.hello("hello world");//global says hello world

在內(nèi)部函數(shù)中,this沒有按預(yù)想的綁定到外層函數(shù)對(duì)象上,而是綁定到了全局對(duì)象。這里普遍被認(rèn)為是JavaScript語言的設(shè)計(jì)錯(cuò)誤,因?yàn)闆]有人想讓內(nèi)部函數(shù)中的this指向全局對(duì)象。一般的處理方式是將this作為變量保存下來,一般約定為that或者self:

var name = "global";
var person = {
    name : "person",
    hello : function(sth){
        var that = this;
        var sayhello = function(sth) {
            console.log(that.name + " says " + sth);
        };
        sayhello(sth);
    }
}
person.hello("hello world");//person says hello world
6. 事件中的this
var ele = document.getElementById("id");
ele.addEventListener("click",function(){
    console.log(this);  //this指向dom元素
});
7. 使用apply和call改變this的指向

apply和call類似,只是后面的參數(shù)是通過一個(gè)數(shù)組傳入,而不是分開傳入。兩者都是將某個(gè)函數(shù)綁定到某個(gè)具體對(duì)象上使用,自然此時(shí)的this會(huì)被顯式的設(shè)置為第一個(gè)參數(shù)。兩者的方法定義:

call( thisArg [,arg1,arg2,… ] );  // 參數(shù)列表,arg1,arg2,...
apply(thisArg [,argArray] );     // 參數(shù)數(shù)組,argArray
var name = "global";
var o = {
    name: "job",
    getName: function(){
        console.log(this.name);
    }
};
o.getName(); // job

//用call或apply改變函數(shù)中this的指向
o.getName.call(this); // global

簡單的總結(jié):

當(dāng)函數(shù)作為對(duì)象的方法調(diào)用時(shí),this指向該對(duì)象。

當(dāng)函數(shù)作為淡出函數(shù)調(diào)用時(shí),this指向全局對(duì)象(嚴(yán)格模式時(shí),為undefined)

構(gòu)造函數(shù)中的this指向新創(chuàng)建的對(duì)象

嵌套函數(shù)中的this不會(huì)繼承上層函數(shù)的this,如果需要,可以用一個(gè)變量保存上層函數(shù)的this。

8. bind()

一個(gè)問題:

$("#ele").click = obj.handler;

如果在handler中用了this,this會(huì)綁定在obj上么?顯然不是,賦值以后,函數(shù)是在回調(diào)中執(zhí)行的,this會(huì)綁定到$(“#some-div”)元素上。那我們?nèi)绾文芙鉀Q回調(diào)函數(shù)綁定的問題?ES5中引入了一個(gè)新的方法,bind():

fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg
當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的this指向.當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效.
arg1, arg2, ...
當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)加上綁定函數(shù)本身的參數(shù)會(huì)按照順序作為原函數(shù)運(yùn)行時(shí)的參數(shù).

該方法創(chuàng)建一個(gè)新函數(shù),稱為綁定函數(shù),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入bind方法的第一個(gè)參數(shù)作為this,傳入bind方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù).

$("#ele").click(person.hello.bind(person));
//相應(yīng)元素被點(diǎn)擊時(shí),輸出person says hello world

該方法也很容易模擬,看下Prototype.js中bind方法的源碼:

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
};
參考資料

js老生常談之this,constructor ,prototype

詳解JavaScript中的this

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/91625.html

相關(guān)文章

  • Javascript重溫OOP之原型原型鏈

    摘要:在構(gòu)造函數(shù)中的中定義的屬性和方法,會(huì)被創(chuàng)建的對(duì)象所繼承下來。從上面的輸出結(jié)果看出,指向了其構(gòu)造函數(shù)的,而本身也是一個(gè)對(duì)象,其內(nèi)部也有屬性,其指向的是直到最后指向,這條原型鏈才結(jié)束。和都指向,說明原型鏈到終止。 prototype原型對(duì)象 每個(gè)函數(shù)都有一個(gè)默認(rèn)的prototype屬性,其實(shí)際上還是一個(gè)對(duì)象,如果被用在繼承中,姑且叫做原型對(duì)象。 在構(gòu)造函數(shù)中的prototype中定義的屬性...

    lindroid 評(píng)論0 收藏0
  • Javascript重溫OOP之JS的解析執(zhí)行過程

    摘要:了解面向?qū)ο缶幊讨?,首先要了解的?zhí)行順序。的解析過程分為兩個(gè)階段預(yù)處理階段與執(zhí)行期。在執(zhí)行階段的執(zhí)行上下文對(duì)象由賦值為指向?qū)?yīng)函數(shù) 了解js面向?qū)ο缶幊讨埃紫纫私鈐s的執(zhí)行順序。js的解析過程分為兩個(gè)階段:預(yù)處理階段與執(zhí)行期。 預(yù)處理階段 在預(yù)處理階段,js會(huì)首先創(chuàng)建一個(gè)執(zhí)行上下文對(duì)象(Execute Context,然后掃描聲明式函數(shù)和用var定義的變量,將其加入執(zhí)行上下文環(huán)...

    xumenger 評(píng)論0 收藏0
  • Javascript重溫OOP之作用域閉包

    摘要:的變量作用域是基于其特有的作用域鏈的。需要注意的是,用創(chuàng)建的函數(shù),其作用域指向全局作用域。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 作用域 定義 在編程語言中,作用域控制著變量與參數(shù)的可見性及生命周期,它能減少名稱沖突,而且提供了自動(dòng)內(nèi)存管理 --javascript 語言精粹 我理解的是,一個(gè)變量、函數(shù)或者成員可以在代碼中訪問到的范圍。 js的變量作...

    JessYanCoding 評(píng)論0 收藏0
  • 重溫基礎(chǔ)】15.JS對(duì)象介紹

    摘要:構(gòu)造函數(shù)通常首字母大寫,用于區(qū)分普通函數(shù)。這種關(guān)系常被稱為原型鏈,它解釋了為何一個(gè)對(duì)象會(huì)擁有定義在其他對(duì)象中的屬性和方法。中所有的對(duì)象,都有一個(gè)屬性,指向?qū)嵗龑?duì)象的構(gòu)造函數(shù)原型由于是個(gè)非標(biāo)準(zhǔn)屬性,因此只有和兩個(gè)瀏覽器支持,標(biāo)準(zhǔn)方法是。 從這篇文章開始,復(fù)習(xí) MDN 中級(jí)教程 的內(nèi)容了,在初級(jí)教程中,我和大家分享了一些比較簡單基礎(chǔ)的知識(shí)點(diǎn),并放在我的 【Cute-JavaScript】系...

    booster 評(píng)論0 收藏0
  • Javascript重溫OOP之面向對(duì)象

    摘要:類的繼承建立繼承關(guān)系修改的指向調(diào)用父類方法調(diào)用父類的構(gòu)造器調(diào)用父類上的方法封裝命名空間是沒有命名空間的,因此可以用對(duì)象模擬。參考資料面向?qū)ο? 面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-oriented programming,OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開發(fā)的方法。對(duì)象指的是類的實(shí)例。它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性?!S基百...

    AbnerMing 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

RancherLabs

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<