问题
1.继承有什么作用?
- 继承是指一个对象直接使用另一对象的属性和方法。
- 作用:
1.当js中的两个对象有很多的共性时,子对象的构造函数没必要重新实现父对象的共性,而可以采用继承的方式,继承父对象的属性和方法,这样子对象在拥有父对象的特性的同时,也可以对自己的特性进行扩充,实现了代码的复用,程序的优化,js中通过原型链来实现继承。
2.用纯js做一些复杂的工具或框架系统就要用到了,比如webgis、或者js框架如jquery、ext等,继承可以减少代码量,有利于维护代码
2.有几种常见创建对象的方式? 举例说明?
字面量形式:
var obj={a:1,b:2}
构造函数方式,先创建一个构造函数(有参数),通过new创建
function people(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
console.log('my name is',this.name)
}
}
var p1=new people('mike',20)工厂模式 ,通过return得到不同的对象返回值,但是得不到对象的类型
function createPeople(name,sex){
var obj={
name:name,
sex:sex,
sayName:function(){
console.log('my name is',this.name)
}
}
return obj
}
var p1=createPeople('nick','man')
var p2=createPeople('mary','woman')-
原型方式 ,在构造函数内部定义对象的属性,在构造函数的原型对象中定义公共的方法,节省代码,优化内存
function createPeople(name,sex){ this.name=name; this.sex=sex; } createPeople.prototype.sayName=function(){ console.log('my name is '+this.name) } var p1= new createPeople('nick','man') p1.sayName() var p2= new createPeople('mary','woman') p2.sayName()
3.下面两种写法有什么区别?
//方法1
function People(name, sex){
this.name = name;
this.sex = sex;
this.printName = function(){
console.log(this.name);
}
}
var p1 = new People('饥人谷', 2)
//方法2
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
}
var p1 = new Person('若愚', 27);
- 方法1,使用的是构造函数的模式,这种方法创建对象的属性和方法都是在构造函数的内部创建并执行,无法实现继承和扩展,每次创建都要重新执行函数,重复创造消耗空间和性能,
- 方法2,使用的原型方式,将对象共有的方法printName在构造函数的原型中定义,这样每次创建对象时,printName方法不会重复创建,当创造对象时,直接调用原型对象中保存的方法,实现了继承,便于扩展,有利于代码简洁,性能的优化
4.Object.create有什么作用?兼容性如何?如何使用?
Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。
兼容性:IE9+,Chrome5+,Firfox4.0+,Opera11.60+,Safari5+
-
使用Object.create()来实现类式继承,语法:
Object.create(*proto,* [ *propertiesObject* ])
,将创建的原型对象赋值到新函数的原型,实现继承
// 构造函数
function people(name,sex){
this.name=name;
this.sex=sex;
}
people.prototype.printName=function(){
console.log('my name is '+this.name)
}
function student(name,sex,grade){
people.call(this,name,sex)
this.grade=grade;
}
//Object.create来使student继承people的方法
function inherit(parent,child){
var _prototype=Object.create(parent.prototype)
_prototype.constructor=child;
child.prototype=_prototype;
}
inherit(people,student)student.prototype.study=function(){ console.log(this.name+'是'+this.grade+'学生') } var p1=new student('nick','man','三年级'); p1.printName(); p1.study();
5.hasOwnProperty有什么作用? 如何使用?
hasOwnProperty()方法用来判断某个对象是否含有指定的自身属性。
所有继承了 Object.prototype的对象都会从原型链上继承到 hasOwnProperty 方法,这个方法可以用来检测一个对象是否含有特定的自身属性,和 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
-
使用 hasOwnProperty方法判断某对象是否含有特定的自身属性
var obj={};
obj.name="nick";
function test() {
obj.newName=obj.name;
delete obj.name;
}obj.hasOwnProperty('name');//true test(); obj.hasOwnProperty('name');//false obj.hasOwnProperty('newName');//true
hasOwnProperty 方法对待自身属性和继承属性的区别
var obj=new Object();
obj.name="mike";//自身属性
obj.hasOwnProperty('name')//true
obj.hasOwnProperty('toString')//false,继承Object的属性
obj.hasOwnProperty('hasOwnProperty')//false,继承Object的属性如果一个对象拥有自己的 hasOwnProperty方法, 则原型链上的同名方法会被遮蔽(shadowed)
var foo={
hasOwnProperty:function () {
return false
},
name:'nick'
}
foo.hasOwnProperty('name')//false,因为一直调用了obj的hasownProperty
//解决方法,直接使用原型链的真正的hasOwnProperty
({}).hasOwnProperty.call(foo, 'bar'); //true,请在控制台直接操作,不然会报错
Object.prototype.hasOwnProperty.call(foo,'name')//true-
遍历一个对象的所有自身属性
var buz = {
fog: 'stack'
};for (var name in buz) { if (buz.hasOwnProperty(name)) { alert("this is fog (" + name + ") for sure. Value: " + buz[name]); } else { alert(name); // toString or something else } }
6.实现Object.create的 polyfill
- 一个shim是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现
- 一个polyfill就是一个用在浏览器API上的shim.我们通常的做法是先检查当前浏览器是否支持某个API,如果不支持的话就加载对应的polyfill.然后新旧浏览器就都可以使用这个API了
function create(obj){
function temp(){};
var newObj=(function(obj){
if(typeof obj!='object'){
throw TypeError('Object prototype may only be an Object or null')
}
temp.prototype=obj;
var prot=new temp();
temp.prototype=null;
return prot
})(obj)
return newObj;
}
var obj={a:1,b:2}
var obj2=create(obj)
console.log(obj2.a)
7.如下代码中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //这里的 call 有什么作用
this.age = age;
}
- call方法执行一个函数,传入执行期上下文和函数的参数,把this的作用域指向了person,在Male函数下执行person(name,sex),因此也继承了person的name和sex属性
8.补全代码,实现继承
function Person(name, sex){
this.name=name;
this.sex=sex;
}
Person.prototype.getName = function(){
return this.name
};
function Male(name, sex, age){
Person.call(this,name,sex)
this.age=age
}
var _prototype=Object.create(Person.prototype);
_prototype.constructor=Male;
Male.prototype=_prototype;
Male.prototype.printName=function(){
console.log('name is '+this.name)
}
Male.prototype.getAge = function(){
return this.age
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();//name is 若愚
代码题
实现如下dialog 弹窗功能, 参考效果
代码预览
效果预览 由于作业上传上去GitHub上有,班级预览项目没有?使用了jsbin预览
- 小结:发现鼠标的拖拽效果不写data缓存数据也能实现。