淺談面向對象的javascript幾個特性

javascript中的thisnew

javascript是一門很靈活的語言,尤其是function。他即可以以面向過程的方式來用,比如:

function getName() {return '張三'
}
getName()

也可以以面向對象的方式來用,比如:

function User() {this.name = '張三'
}var user = new User()

javascript是如何實現面向對象編程的呢?他提供了new這個關健字,有了new就可以把對象進行實例化,比如:

function User(name, age){this.name = namethis.age = age
}
var zs = new User('zs', 20)
var ls = new User('ls', 30)

new出來的兩個實例,會開辟兩塊新的內存區域,來保存這些數據,同時有指針指向對象User。所以就有instanceof這個運算符,這個運算符的意思就是:a是不是A的實例。比如上例:zs instanceof User的返回值是true
即然是面向對象的編程語言,那this也是不可或缺的。在javascript中,this永遠指向的是他的調用者。要理解這句話,我們舉幾個例子:

例子1

function test(){this.name = 'zs'
}
test()

當執行完成之后,這個name會直接掛載到window下面,因為是這樣執行的:winow.test()

例子2

var game = document.getElementById('game')
game.addEventListener('click', function () {setTimeout(function () {this.innerText = 'Clicked'}, 1000)
})

這個例子很簡單,點擊某個元素的時候,1秒后,讓他里面的html改成Clicked,可是你發現這樣不好使,就是因為this指向的問題,因為這里面的this也指向window了,所以你執行window.innerText會返回Clicked

例子3

function User(name) {this.name = namethis.getName = function () {console.log(this.name)}
}
var u = new User('zs')
u.getName()

這里面的this的指向沒有問題,因為按照之前的原則,調用者是u,也就是User的實例,所以在方法getName中,this.name相當于u.name,所以打印出zs

prototype和__proto__

prototype

javascript是面向對象的語言,這個上面已經提過了,其他面向對象語言有一個必備我就是繼承,很顯然在ES6之前,沒有extends這個關鍵字,那么,javascript就是利用prototype的原型鏈來實現繼承。先記住這句話,我們一會會說到繼承。prototype其實只是對象的一個屬性,在Chrome控制臺下,可以直接看出來,但是這個屬性很特殊,這個屬性下可以掛載任何的對象、方法、屬性,而且掛載的東西可以反映到實例下對象上。說的比較繞,我們看個例子:

function User(name) {this.name = name
}
User.prototype.getName = function () {console.log(this.name)
}
var u = new User('zs')
u.getName()

我們在User.prototype上面掛載了getName的方法,在下面實例化User之后的u,就可以訪問這個方法。
看到這,你可以有個疑問,既然是給實例化對象用的,那下面這種方式豈不是更好、更直觀?

function User(name) {this.name = namethis.getName = function () {console.log(this.name)}
}
var u = new User('zs')
u.getName()

如果我們和Java語言進行對應,User相當是Classname相當于屬性,getName相當于里面的方法,完美映射!可以這樣有一個問題啊,就是太費內存了。因為每new一個對象,都會占用一塊內存區域,這樣User里面方法屬性越多,那么每個實例化的對象都會對這些進行 深復制,那么占用的內存空間就越大。那么javascript是如何通過prototype來解決內存占用的問題的呢?這就需要引用__proto__

__proto__

定義:__proto__是存在于實例化后對象的一個屬性,并且指向原對象的prototype屬性
比如上例中的u.__proto__ === User.prototype返回的是true。可以在Chrome控制臺下查看u.__proto__

你會發現,不對吧,User對象下也有__proto__啊。那是因為User也是Function的實例,不信你可以試一下User.__proto__ === Function.prototype的返回值。其實我們這樣定義函數:function test(){}是一個語法糖的寫法,全拼應該是這樣:var test = new Function('alert(1)')

現在我們來解釋為什么使用prototype能節省內存。不知道你有沒有注意到上面一句代碼u.__proto__ === User.prototype,我為什么要使用三等?因為三等號除了值、類型外,內存地址也必須是相等的,也就是說User不管實例化多少對象,他們的prototype只有一份,放在User里。客戶端的瀏覽器環境不像服務器,內存還是比較緊張的,所以javascript通過這種方式,來解決內存占用問題。

繼承

方式一:直接繼承

先舉個例子:

var Animal = function (name) {this.name = name
}
Animal.prototype.walk = function () {console.log('I can walk!')
}
Animal.prototype.getName = function () {console.log('My name is ' + this.name + '!')
}var Dog = function (name) {this.name = name
}
Dog.prototype = Animal.prototypevar d = new Dog('Tom')
d.getName()
d.walk()

我們建立一個父類Animal對象,建立一個子類Dog,我們想讓Dog也有walk方法和getName方法,通過上面對prototype的了解,我們最先想到的是Dog.prototype = Animal.prototype,這樣子類和父類的prototype相等,那子類就有父類所有方法嘍,繼承鏈條是這樣的:d.__proto__ === Dog.prototype === Animal.prototype
這樣很直觀,但是也有一個比較嚴重的問題。我們在擴展Dog的時候,同時父類也會有對應的方法,這很顯然是一個很嚴重的問題。

方式二:實例化繼承

為了解決上面的問題,我們需要引入一個空函數,這個空函數做為橋梁,把子類和父類之間的連接切斷。實現如下:

var F = function () {}
F.prototype = Animal.prototype
Dog.prototype = new F()Dog.prototype.say = function () {console.log('Say')
}
  • 為什么是Dog.prototype = new F()呢?因為這樣即可以繼承Animal的所有方法,他的原型鏈是這樣的:
d.__proto__ --> Dog.prototype --> new F().__proto__

執行walk方法,F已經有了,所以就不會再找Animal

  • 新增加的方法又不影響父類,這句怎么講?因實例化的對象沒有prototype屬性!所以不會影響

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455591.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455591.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455591.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Netty】ChannelHandler和ChannelPipeline

一、前言 前面學習了Netty的ByteBuf,接著學習ChannelHandler和ChannelPipeline。 二、ChannelHandler和ChannelPipeline 2.1 ChannelHandler 在ChannelPipeline中,ChannelHandler可以被鏈在一起處理用戶邏輯。 1. Channel生命周期 Channel接口定義了一個…

TS流頭部的調整字段

見 http://hi.baidu.com/xumingxsh/blog/item/7b178903f1fa98014afb512f.html http://hi.baidu.com/xumingxsh/blog/item/ba50dba320a10da3caefd02f.html

electron 入坑記

最近有個想法,想寫個簡單的應用程序.平時在 Mac上開發,最終有可能運行在 Windows 上.看了一下,Electron 比較簡單,應該可以一試. 關于安裝 我機器上是有 Node 環境的,按著官方教程 直接 npm install electron 結果運行到 npm install.js就不到了..下午上班有事,也沒管他,結果一…

自動駕駛安全駕駛規則_自動駕駛知識科普 自動駕駛汽車的七大核心技術

自動駕駛技術的本質是用機器視角去模擬人類駕駛員的行為,其技術框架可以分為三個環節:感知層、決策層 和執行層,具體涉及傳感器、計算平臺、算法、高精度地圖、OS、HMI等 多個技術模塊。目前自動駕駛L3商業化技術已經成熟,L4級/L5…

orcal數據操作

1.將數據庫ZHSY完全導出,用戶名baseusernj密碼baseusernj導出到D:\daochu.dmp中 exp baseusernj/baseusernjZHSY filed:\daochu.dmp fully exp baseuserhf/baseuserhfZJCPDB fileC:\105hf.dmp ownerbaseuserhf 2.導入那個數據庫的用戶就寫那個,第一個是用戶名&#…

H264實時編碼及NALU,RTP傳輸(ZZ)

rfc3984 Standards Track [Page 2] RFC 3984 RTP Payload Format for H.264 Video February 2005 1. 按照RFC3984協議實現H264視頻流媒體nalu單元 包起始 0x 00 00 00 01H.264 NAL格式及分析器http://hi.baidu.com/zsw%5Fdavy/b ... c409cc7cd92ace.htmlhttp://hi.b…

學習具體計劃書

計劃書10大行動&#xff1a;1. 學習的時候不玩手機學習的時候把手機放在抽屜里&#xff0c;靜音2. 及時復習學完一個章節的知識及時復習覺得有做分享的價值就做分享錄視頻3. 不學習的時間要好好利用花時間做好吃的&#xff0c;把身體弄好多看看心理學的書&#xff0c;<接觸青…

初識python

課程介紹: python語言:python語言是一種計算機程序設計語言,實現人機交互的語言 python的課程設計python基礎 (python開發工程師)數據庫和SQL開發 (數據分析工程師)網絡爬蟲 (網絡爬蟲工程師)高數和數據分析 (數據分析工程師)人工智能和機器學習 …

photoshop最全快捷鍵列表

一、工具箱(多種工具共用一個快捷鍵的可同時按【Shift】加此快捷鍵選取) 矩形、橢圓選框工具 【M】 移動工具 【V】 套索、多邊形套索、磁性套索 【L】 魔棒工具 【W】 裁剪工具 【C】 切片工具、切片選擇工具 【K】 噴槍工具 【J】 畫筆工具、鉛筆工具 【B】 像皮圖章、圖案圖…

python實例化對象做實參_如何在Python中記住類實例化?

好的&#xff0c;這是真實的場景&#xff1a;我正在編寫一個應用程序&#xff0c;我有一個類&#xff0c;它表示某種類型的文件&#xff08;在我的例子中&#xff0c;這是照片&#xff0c;但細節與問題無關&#xff09;。照片類的每個實例對于照片的文件名都應該是唯一的。 問題…

bupt summer training for 16 #3 ——構造

https://vjudge.net/contest/172464 后來補題發現這場做的可真他媽傻逼 A.簽到傻逼題&#xff0c;自己分情況 1 #include <cstdio>2 #include <vector>3 #include <algorithm>4 5 using std::vector;6 using std::sort;7 8 typedef long long ll;9 10 int n…

Python02期(北京)課程筆記索引

day01 初始python關于使用notepad運行python程序注釋和語句分類 day02 命名方式和關鍵字數據類型數據類型轉換 day03 變量與數據類型運算和運算符進制轉換 day04 循環結構 day05 函數概述 day06 nonlocal和global 關鍵字詳解 day07 python核心,內建函數高階函數字…

python常用快捷鍵、寫代碼事半功倍_Pycharm常用快捷鍵總結及配置方法

工欲善其事必先利其器&#xff0c;Python開發利器Pycharm常用快捷鍵以及配置如下&#xff0c;相信有了這些快捷鍵&#xff0c;你的開發會事半功倍 一 常用快捷鍵 編輯類&#xff1a; Ctrl D 復制選定的區域或行 Ctrl Y 刪除選定的行 Ctrl Alt L 代碼格式化 Ctrl Alt O 優…

PHP中的魔術常量

魔術常量 PHP 向它運行的任何腳本提供了大量的預定義常量。不過很多常量都是由不同的擴展庫定義的&#xff0c;只有在加載了這些擴展庫時才會出現&#xff0c;或者動態加載后&#xff0c;或者在編譯時已經包括進去了。 有八個魔術常量它們的值隨著它們在代碼中的位置改變而改…

Java中的繼承性特性

繼承性是java中的第二特性之一。而繼承性最為關鍵的地方為&#xff1a;代碼重用性的問題&#xff0c;利用繼承性可以從已有的類中繼續派生出新的子類&#xff0c;也可以利用子類擴展出更多的操作功能。 繼承性的實現代碼為&#xff1a;class 子類 extends 父類{ } 有以下3點說…

10大html5前端框架

Bootstrap 首先說 Bootstrap&#xff0c;估計你也猜到會先說或者一定會有這個( 呵呵了 )&#xff0c;這是說明它的強大之處&#xff0c;擁有框架一壁江山的勢氣。自己剛入道的時候本著代碼任何一個字母都得自己敲出來擋我者廢的決心&#xff0c;來讓自己成長。結果受到周圍各 種…

多媒體技術復習匯總 收藏

多媒體技術復習匯總 收藏 1. 什么是媒體&#xff1a;媒體是信息表示和傳輸的載體。2. 媒體分類&#xff1a;感覺媒體&#xff0c;表示媒體&#xff0c;表現媒體&#xff0c;存儲媒體&#xff0c;傳輸媒體3. 多媒體技術的定義和特點&#xff1a;多媒體技…

PHP中的語法特點小結

PHP中的語法特點小結 1.PHP的變量開頭要加上$符號,見到$就知道這個是一個變量 2.PHP中的常量才是不用加$符號的 3.PHP中$可以用來嵌套使用,從而實現動態的變量名的層級調用 4.PHP程序<?php開頭,結尾可以加上?>,也可以不加 5.PHP中的常量有著魔術常量(系統自帶的) 6.PH…

滾動行為

new router({ scrollBehavior (to, from, savaPosition) { if(savePosition) { //歷史記錄的前進后退記住的之前滾動到的位置 return savePosition } else { return {x: 0, y: 0} } //history模式下 定位到某個元素失效的解決辦法 if(to.hash) { return { selector: to.h…