一、问答题
1.继承有什么作用? (难度:***)
继承机制使得不同的实例可以共享构造函数的原型对象的属性和方法,以提高代码的复用性;
2.有几种常见创建对象的方式? 举例说明? (难度:****)
(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');
函数createPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象,可以无数次的调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
(2)构造函数模式
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构造函数与createPerson函数的不同在于:
- 没有显示的创建对象
- 直接将属性和方法赋给this对象
- 没有return语句
要创建新对象必须用new,它会干四件事:
- 创建一个新对象,作为this
- this.proto指向构造函数的prototype
- 执行构造函数的代码
- 返回新对象(没有return对象就return this)
构造函数的问题:
- 每个方法都要在每个实例上重新创建一遍;
(3)原型&构造模式
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提出的一个新的方法,它可以传入一个对象作为该方法返回的对象的原型对象;
//使用字面量创建一个对象作为实例的原型对象;
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()的内在原理:
Object.create = function(obj){
function F(){};
F.prototype = obj;
return new F(){};
}
这种创建对象的方法优点是比较简单,缺点是作为原型对象的对象的属性和方法是公有变量,容易遭受修改,实例对象之间也不能共享数据;
3.下面两种写法有什么区别? (难度:***)
第一种用的是构造函数的方法创建对象,第二种是用构造函数和原型结合的方法构造函数;
第一种方法的缺陷是,资源重复浪费,需要在每一个对象实例都创建一个printName的方法,每个printName都占用内存;
第二种方法,将共有的方法部署在原型中,这样可以达到节省内存的效果;
4. Object.create 有什么作用?兼容性如何?如何使用? (难度:***)
- Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。
- 目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署:
if(!Object.create){
Object.create = function(obj){
function F(){}
F.prototype = obj;
return new F();
}
}
- 实例详见第2题创建对象方法之Object.create法
5.hasOwnProperty有什么作用? 如何使用? (难度:***)
对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。
Date.hasOwnProperty('length')// true
Date.hasOwnProperty('toString')// false
hasOwnProperty
方法是JavaScript之中唯一一个处理对象属性时,不会遍历原型链的方法。
6.实现Object.create的 polyfill,如:(ps: 写个 函数create,实现 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);
//构造函数Person在构造函数Male作用域下执行,以实现构造函数属性的继承,call具有改变作用域的作用
this.age = age;
}
8. 补全代码,实现继承 (难度:****)
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)实现如下dialog 弹窗功能, 参考效果 (难度:*****)
//功能描述:
// 1. 可使用 dialog.open() 去打开弹窗
// 2. 当点击确定、取消时可使用用户自定义事件
// 3. dialog 可拖动
// 4. 允许页面展示多个 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('确定');
}
});
});