一、問答題
1.繼承有什么作用? (難度:***)
繼承機(jī)制使得不同的實(shí)例可以共享構(gòu)造函數(shù)的原型對(duì)象的屬性和方法浴鸿,以提高代碼的復(fù)用性推励;
2.有幾種常見創(chuàng)建對(duì)象的方式? 舉例說明? (難度:****)
(1)工廠模式
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name)
}
return o
}
var person1 = createPerson('lucy',29,'engineer');
var person2 = createPerson('adam',25,'doctor');
函數(shù)createPerson()能夠根據(jù)接受的參數(shù)來構(gòu)建一個(gè)包含所有必要信息的Person對(duì)象,可以無數(shù)次的調(diào)用這個(gè)函數(shù),而每次它都會(huì)返回一個(gè)包含三個(gè)屬性一個(gè)方法的對(duì)象吴旋。工廠模式雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問題损肛,但卻沒有解決對(duì)象識(shí)別的問題(即怎樣知道一個(gè)對(duì)象的類型)。
(2)構(gòu)造函數(shù)模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name)
}
}
var person1 = new Person('lucy',29,'engineer');
var person2 = new Person('adam',25,'doctor');
Person構(gòu)造函數(shù)與createPerson函數(shù)的不同在于:
- 沒有顯示的創(chuàng)建對(duì)象
- 直接將屬性和方法賦給this對(duì)象
- 沒有return語句
要?jiǎng)?chuàng)建新對(duì)象必須用new荣瑟,它會(huì)干四件事:
- 創(chuàng)建一個(gè)新對(duì)象治拿,作為this
- this.proto指向構(gòu)造函數(shù)的prototype
- 執(zhí)行構(gòu)造函數(shù)的代碼
- 返回新對(duì)象(沒有return對(duì)象就return this)
構(gòu)造函數(shù)的問題:
- 每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍;
(3)原型&構(gòu)造模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype.sayName = function(){
alert(this.name)
}
var person1 = new Person('lucy',29,'engineer');
var person2 = new Person('adam',25,'doctor');
(4)Object.create()法
Object.create()是ES5提出的一個(gè)新的方法笆焰,它可以傳入一個(gè)對(duì)象作為該方法返回的對(duì)象的原型對(duì)象劫谅;
//使用字面量創(chuàng)建一個(gè)對(duì)象作為實(shí)例的原型對(duì)象;
var Person = {
name: 'Jack',
age:'18',
sayName:function(){
console.log(this.name)
}
}
var Jack = Object.create(Person)
console.log(Jack.name)//Jack
console.log(Jack.age)//18
Jack.sayName()//Jack
Object.create()的內(nèi)在原理:
Object.create = function(obj){
function F(){};
F.prototype = obj;
return new F(){};
}
這種創(chuàng)建對(duì)象的方法優(yōu)點(diǎn)是比較簡(jiǎn)單嚷掠,缺點(diǎn)是作為原型對(duì)象的對(duì)象的屬性和方法是公有變量捏检,容易遭受修改,實(shí)例對(duì)象之間也不能共享數(shù)據(jù)不皆;
3.下面兩種寫法有什么區(qū)別? (難度:***)
第一種用的是構(gòu)造函數(shù)的方法創(chuàng)建對(duì)象贯城,第二種是用構(gòu)造函數(shù)和原型結(jié)合的方法構(gòu)造函數(shù);
第一種方法的缺陷是霹娄,資源重復(fù)浪費(fèi)能犯,需要在每一個(gè)對(duì)象實(shí)例都創(chuàng)建一個(gè)printName的方法,每個(gè)printName都占用內(nèi)存犬耻;
第二種方法踩晶,將共有的方法部署在原型中,這樣可以達(dá)到節(jié)省內(nèi)存的效果枕磁;
4. Object.create 有什么作用渡蜻?兼容性如何?如何使用计济? (難度:***)
- Object.create() 方法創(chuàng)建一個(gè)擁有指定原型和若干個(gè)指定屬性的對(duì)象晴楔。
- 目前,各大瀏覽器的最新版本(包括IE9)都部署了這個(gè)方法峭咒。如果遇到老式瀏覽器税弃,可以用下面的代碼自行部署:
if(!Object.create){
Object.create = function(obj){
function F(){}
F.prototype = obj;
return new F();
}
}
- 實(shí)例詳見第2題創(chuàng)建對(duì)象方法之Object.create法
5.hasOwnProperty有什么作用? 如何使用凑队? (難度:***)
對(duì)象實(shí)例的hasOwnProperty方法返回一個(gè)布爾值则果,用于判斷某個(gè)屬性定義在對(duì)象自身,還是定義在原型鏈上漩氨。
Date.hasOwnProperty('length')// true
Date.hasOwnProperty('toString')// false
hasOwnProperty
方法是JavaScript之中唯一一個(gè)處理對(duì)象屬性時(shí)西壮,不會(huì)遍歷原型鏈的方法。
6.實(shí)現(xiàn)Object.create的 polyfill叫惊,如:(ps: 寫個(gè) 函數(shù)create款青,實(shí)現(xiàn) Object.create 的功能) (難度:****)
function create(obj){
function F(){}
F.prototype = obj;
return new F();
}
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
console.log(this.name)
}
function Male(male,name,age){
Person.call(this,name,age)
this.male = male;
}
Male.prototype = create(Person.prototype);
var adam = new Male('boy','adam',23);
adam.sayName()//adam
7.如下代碼中call的作用是什么? (難度:****)
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex);
//構(gòu)造函數(shù)Person在構(gòu)造函數(shù)Male作用域下執(zhí)行,以實(shí)現(xiàn)構(gòu)造函數(shù)屬性的繼承霍狰,call具有改變作用域的作用
this.age = age;
}
8. 補(bǔ)全代碼抡草,實(shí)現(xiàn)繼承 (難度:****)
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this,name,sex);
this.age = age;
}
function inherit(Sup,Sub){
var _prototype = Object.create(Sup.prototype);
_prototype.constructor = Sub;
Sub.prototype = _prototype;
}
inherit(Person,Male);
Male.prototype.getAge = function(){
console.log(this.age);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName(); //若愚
ruoyu.getAge(); //27
二饰及、代碼
(1)實(shí)現(xiàn)如下dialog 彈窗功能, 參考效果 (難度:*****)
//功能描述:
// 1. 可使用 dialog.open() 去打開彈窗
// 2. 當(dāng)點(diǎn)擊確定康震、取消時(shí)可使用用戶自定義事件
// 3. dialog 可拖動(dòng)
// 4. 允許頁面展示多個(gè) dialog
function Dialog(){
}
var tpl = '<ul><li>列表1</li><li>列表2</li><li>列表1</li><li>列表1</li></ul>';
$('#open4').on('click',function(){
var dialog4 = new Dialog();
dialog4.open({
title: '歡迎來到饑人谷',
message: tpl,
isShowCloseBtn: true,
isShowConfirmBtn: true,
onClose: function(){
alert('close')
},
onConfirm: function(){
alert('確定');
}
});
});