javascript原型和原型鏈有什么特點(diǎn)
每個(gè)對象都會(huì)在其內(nèi)部初始化一個(gè)屬性,就是prototype(原型),當(dāng)我們訪問一個(gè)對象的屬性時(shí),
如果這個(gè)對象內(nèi)部不存在這個(gè)屬性,那么他就會(huì)去prototype里找這個(gè)屬性,這個(gè)prototype又會(huì)有自己的prototype,
于是就這樣一直找下去,也就是我們平時(shí)所說的原型鏈的概念。
關(guān)系:instance.constructor.prototype = instance.__proto__
特點(diǎn):
JavaScript對象是通過引用來傳遞的,我們創(chuàng)建的每個(gè)新對象實(shí)體中并沒有一份屬于自己的原型副本。當(dāng)我們修改原型時(shí),與之相關(guān)的對象也會(huì)繼承這一改變。
當(dāng)我們需要一個(gè)屬性的時(shí),Javascript引擎會(huì)先看當(dāng)前對象中是否有這個(gè)屬性, 如果沒有的話,
就會(huì)查找他的Prototype對象是否有這個(gè)屬性,如此遞推下去,一直檢索到 Object 內(nèi)建對象。
function Func(){}
Func.prototype.name = “Sean”;
Func.prototype.getInfo = function() {
return this.name;
}
var person = new Func();//現(xiàn)在可以參考var person = Object.create(oldObject);
console.log(person.getInfo());//它擁有了Func的屬性和方法
//“Sean”
console.log(Func.prototype);
// Func { name=“Sean”, getInfo=function()}
寫一個(gè)通用的事件偵聽器函數(shù)。
// event(事件)工具集,來源:github.com/markyun
markyun.Event = {
// 頁面加載完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != ‘function’) {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
// 視能力分別使用dom0||dom2||IE方式 來綁定事件
// 參數(shù): 操作的元素,事件名稱 ,事件處理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
//事件類型、需要執(zhí)行的函數(shù)、是否捕捉
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent(‘on’ + type, function() {
handler.call(element);
});
} else {
element[‘on’ + type] = handler;
}
},
// 移除事件
removeEvent : function(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.datachEvent) {
element.detachEvent(‘on’ + type, handler);
} else {
element[‘on’ + type] = null;
}
},
// 阻止事件 (主要是事件冒泡,因?yàn)镮E不支持事件捕獲)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
// 取消事件的默認(rèn)行為
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
// 獲取事件目標(biāo)
getTarget : function(event) {
return event.target || event.srcElement;
},
// 獲取event對象的引用,取到事件的所有信息,確保隨時(shí)能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
};
對Node的優(yōu)點(diǎn)和缺點(diǎn)提出了自己的看法?
*(優(yōu)點(diǎn))因?yàn)镹ode是基于事件驅(qū)動(dòng)和無阻塞的,所以非常適合處理并發(fā)請求,
因此構(gòu)建在Node上的代理服務(wù)器相比其他技術(shù)實(shí)現(xiàn)(如Ruby)的服務(wù)器表現(xiàn)要好得多。
此外,與Node代理服務(wù)器交互的客戶端代碼是由javascript語言編寫的,
因此客戶端和服務(wù)器端都用同一種語言編寫,這是非常美妙的事情。
*(缺點(diǎn))Node是一個(gè)相對新的開源項(xiàng)目,所以不太穩(wěn)定,它總是一直在變,
而且缺少足夠多的第三方庫支持??雌饋?,就像是Ruby/Rails當(dāng)年的樣子。
Javascript如何實(shí)現(xiàn)繼承?
1、構(gòu)造繼承
2、原型繼承
3、實(shí)例繼承
4、拷貝繼承
原型prototype機(jī)制或apply和call方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。
function Parent(){
this.name = ‘wang’;
}
function Child(){
this.age = 28;
}
Child.prototype = new Parent();//繼承了Parent,通過原型
var demo = new Child();
alert(demo.age);
alert(demo.name);//得到被繼承的屬性
}
Javascript作用鏈域?
全局函數(shù)無法查看局部函數(shù)的內(nèi)部細(xì)節(jié),但局部函數(shù)可以查看其上層的函數(shù)細(xì)節(jié),直至全局細(xì)節(jié)。
當(dāng)需要從局部函數(shù)查找某一屬性或方法時(shí),如果當(dāng)前作用域沒有找到,就會(huì)上溯到上層作用域查找,
直至全局函數(shù),這種組織形式就是作用域鏈。
javascript創(chuàng)建對象的幾種方式?
javascript創(chuàng)建對象簡單的說,無非就是使用內(nèi)置對象或各種自定義對象,當(dāng)然還可以用JSON;但寫法有很多種,也能混合使用。
1、對象字面量的方式
person={firstname:“Mark”,lastname:“Yun”,age:25,eyecolor:“black”};
2、用function來模擬無參的構(gòu)造函數(shù)
function Person(){}
var person=new Person();//定義一個(gè)function,如果使用new“實(shí)例化”,該function可以看作是一個(gè)Class
person.name=“Mark”;
person.age=“25”;
person.work=function(){
alert(person.name+“ hello.。?!保?
}
person.work();
3、用function來模擬參構(gòu)造函數(shù)來實(shí)現(xiàn)(用this關(guān)鍵字定義構(gòu)造的上下文屬性)
function Pet(name,age,hobby){
this.name=name;//this作用域:當(dāng)前對象
this.age=age;
this.hobby=hobby;
this.eat=function(){
alert(“我叫”+this.name+“,我喜歡”+this.hobby+“,是個(gè)程序員”);
}
}
var maidou =new Pet(“麥兜”,25,“coding”);//實(shí)例化、創(chuàng)建對象
maidou.eat();//調(diào)用eat方法
4、用工廠方式來創(chuàng)建(內(nèi)置對象)
var wcDog =new Object();
wcDog.name=“旺財(cái)”;
wcDog.age=3;
wcDog.work=function(){
alert(“我是”+wcDog.name+“,汪汪汪。。。。。?!保?
}
wcDog.work();
5、用原型方式來創(chuàng)建
function Dog(){
}
Dog.prototype.name=“旺財(cái)”;
Dog.prototype.eat=function(){
alert(this.name+“是個(gè)吃貨”);
}
var wangcai =new Dog();
wangcai.eat();
5、用混合方式來創(chuàng)建
function Car(name,price){
this.name=name;
this.price=price;
}
Car.prototype.sell=function(){
alert(“我是”+this.name+“,我現(xiàn)在賣”+this.price+“萬元”);
}
var camry =new Car(“凱美瑞”,27);
camry.sell();
CSS優(yōu)先級算法如何計(jì)算? * 優(yōu)先級就近原則,同權(quán)重情況下樣式定義最近者為準(zhǔn);
載入樣式以最后載入的定位為準(zhǔn);
優(yōu)先級為:
?。mportant 》 id 》 class 》 tag
important 比 內(nèi)聯(lián)優(yōu)先級高
iframe有那些缺點(diǎn)?
*iframe會(huì)阻塞主頁面的Onload事件;
*搜索引擎的檢索程序無法解讀這種頁面,不利于SEO;
*iframe和主頁面共享連接池,而瀏覽器對相同域的連接有限制,所以會(huì)影響頁面的并行加載。
使用iframe之前需要考慮這兩個(gè)缺點(diǎn)。如果需要使用iframe,最好是通過javascript
動(dòng)態(tài)給iframe添加src屬性值,這樣可以繞開以上兩個(gè)問題。
HTML5的離線儲(chǔ)存怎么使用,工作原理能不能解釋一下?
在用戶沒有與因特網(wǎng)連接時(shí),可以正常訪問站點(diǎn)或應(yīng)用,在用戶與因特網(wǎng)連接時(shí),更新用戶機(jī)器上的緩存文件。
原理:HTML5的離線存儲(chǔ)是基于一個(gè)新建的.appcache文件的緩存機(jī)制(不是存儲(chǔ)技術(shù)),通過這個(gè)文件上的解析清單離線存儲(chǔ)資源,這些資源就會(huì)像cookie一樣被存儲(chǔ)了下來。之后當(dāng)網(wǎng)絡(luò)在處于離線狀態(tài)下時(shí),瀏覽器會(huì)通過被離線存儲(chǔ)的數(shù)據(jù)進(jìn)行頁面展示。
如何使用:
1、頁面頭部像下面一樣加入一個(gè)manifest的屬性;
2、在cache.manifest文件的編寫離線存儲(chǔ)的資源;
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
3、在離線狀態(tài)時(shí),操作window.applicationCache進(jìn)行需求實(shí)現(xiàn)。
Ajax是什么? 如何創(chuàng)建一個(gè)Ajax?
ajax的全稱:AsynchronousJavascript And XML。
異步傳輸+js+xml。
所謂異步,在這里簡單地解釋就是:向服務(wù)器發(fā)送請求的時(shí)候,我們不必等待結(jié)果,而是可以同時(shí)做其他的事情,等到有了結(jié)果它自己會(huì)根據(jù)設(shè)定進(jìn)行后續(xù)操作,與此同時(shí),頁面是不會(huì)發(fā)生整頁刷新的,提高了用戶體驗(yàn)。
?。?)創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個(gè)異步調(diào)用對象
(2)創(chuàng)建一個(gè)新的HTTP請求,并指定該HTTP請求的方法、URL及驗(yàn)證信息
?。?)設(shè)置響應(yīng)HTTP請求狀態(tài)變化的函數(shù)
?。?)發(fā)送HTTP請求
?。?)獲取異步調(diào)用返回的數(shù)據(jù)
?。?)使用JavaScript和DOM實(shí)現(xiàn)局部刷新
同步和異步的區(qū)別?
同步:瀏覽器訪問服務(wù)器請求,用戶看得到頁面刷新,重新發(fā)請求,等請求完,頁面刷新,新內(nèi)容出現(xiàn),用戶看到新內(nèi)容,j進(jìn)行下一步操作。
異步:瀏覽器訪問服務(wù)器請求,用戶正常操作,瀏覽器后端進(jìn)行請求。等請求完,頁面不刷新,新內(nèi)容也會(huì)出現(xiàn),用戶看到新內(nèi)容。
AMD(Modules/Asynchronous-Definition)、CMD(Common ModuleDefinition)規(guī)范區(qū)別?
AsynchronousModule Definition,異步模塊定義,所有的模塊將被異步加載,模塊加載不影響后面語句運(yùn)行。所有依賴某些模塊的語句均放置在回調(diào)函數(shù)中。
區(qū)別:
1. 對于依賴的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過RequireJS 從 2.0 開始,也改成可以延遲執(zhí)行(根據(jù)寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
2. CMD 推崇依賴就近,AMD 推崇依賴前置??创a:
// CMD
define(function(require,exports, module) {
var a = require(‘。/a’)
a.doSomething()
// 此處略去 100 行
var b = require(‘。/b’) // 依賴可以就近書寫
b.doSomething()
// 。。。
})
// AMD 默認(rèn)推薦
define([‘。/a’,‘。/b’], function(a, b) { // 依賴必須一開始就寫好
a.doSomething()
// 此處略去 100 行
b.doSomething()
// 。。。
})
DOM操作——怎樣添加、移除、移動(dòng)、復(fù)制、創(chuàng)建和查找節(jié)點(diǎn)?
?。?)創(chuàng)建新節(jié)點(diǎn)
createDocumentFragment() //創(chuàng)建一個(gè)DOM片段
createElement() //創(chuàng)建一個(gè)具體的元素
createTextNode() //創(chuàng)建一個(gè)文本節(jié)點(diǎn)
?。?)添加、移除、替換、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子節(jié)點(diǎn)前插入一個(gè)新的子節(jié)點(diǎn)
?。?)查找
getElementsByTagName() //通過標(biāo)簽名稱
getElementsByName() //通過元素的Name屬性的值(IE容錯(cuò)能力較強(qiáng),會(huì)得到一個(gè)數(shù)組,其中包括id等于name值的)
getElementById() //通過元素Id,唯一性
什么叫優(yōu)雅降級和漸進(jìn)增強(qiáng)?
優(yōu)雅降級:Web站點(diǎn)在所有新式瀏覽器中都能正常工作,如果用戶使用的是老式瀏覽器,則代碼會(huì)針對舊版本的IE進(jìn)行降級處理了,使之在舊式瀏覽器上以某種形式降級體驗(yàn)卻不至于完全不能用。
如:border-shadow
漸進(jìn)增強(qiáng):從被所有瀏覽器支持的基本功能開始,逐步地添加那些只有新版本瀏覽器才支持的功能,向頁面增加不影響基礎(chǔ)瀏覽器的額外樣式和功能的。當(dāng)瀏覽器支持時(shí),它們會(huì)自動(dòng)地呈現(xiàn)出來并發(fā)揮作用。
如:默認(rèn)使用flash上傳,但如果瀏覽器支持HTML5 的文件上傳功能,則使用HTML5實(shí)現(xiàn)更好的體驗(yàn);
jsonp的原理是動(dòng)態(tài)插入script標(biāo)簽
跨子域可以采用iframe proxy的方式,支持GET和POST,支持異步POST。缺點(diǎn)是:范圍較窄,限定在“跨子域”,而且需要在目標(biāo)服務(wù)器增加額外的文件。
JSONP的方式,支持雙向通信。只支持GET。缺點(diǎn)是:不支持POST,同時(shí)需要目標(biāo)服務(wù)器在服務(wù)端支持。
iframe的window.name的方式,支持跨主域。缺點(diǎn)是:不支持POST,不過已經(jīng)很贊了:)
HTML5postMessage,支持雙向通信。缺點(diǎn)是:僅限于HTML5。結(jié)合window.name的方式,就很贊了
iframe + location.hash的方式跨主域,功能強(qiáng)大,兼容性好,支持跨域的js調(diào)用,支持雙向通信。缺點(diǎn)是:太復(fù)雜,會(huì)嵌套太多的iframe,同時(shí)數(shù)據(jù)直接寫在url中,數(shù)據(jù)大小受限而且數(shù)據(jù)暴露在外。
利用Flash跨域,優(yōu)點(diǎn)是支持強(qiáng)大,相對簡單。缺點(diǎn)是:依賴flash,需要在服務(wù)器更目錄放置crossdomain.xml文件。
為什么要有同源限制?
我們舉例說明:比如一個(gè)黑客程序,他利用Iframe把真正的銀行登錄頁面嵌到他的頁面上,當(dāng)你使用真實(shí)的用戶名,密碼登錄時(shí),他的頁面就可以通過Javascript讀取到你的表單中input中的內(nèi)容,這樣用戶名,密碼就輕松到手了。
作用域鏈的理解
每一段js代碼(全局代碼或函數(shù))都有一個(gè)與之關(guān)聯(lián)的作用域鏈(scope chain)。
當(dāng)js需要查找變量x值的時(shí)候(這個(gè)過程稱為變量解析(variable resolution)),它會(huì)從鏈的第一個(gè)對象開始查找,如果這個(gè)對象有一個(gè)名為x的屬性,則會(huì)直接使用這個(gè)屬性的值,如果第一個(gè)對象中沒有名為x的屬性,js會(huì)繼續(xù)查找鏈上的下一個(gè)對象。如果第二個(gè)對象依然沒有名為x的屬性,則會(huì)繼續(xù)查找下一個(gè),以此類推。
如果作用域鏈上沒有任何一個(gè)對象含有屬性x,那么就認(rèn)為這段代碼的作用域鏈上不存在x,并最終拋出一個(gè)引用錯(cuò)誤(ReferenceError)異常。
評論