JavaScript高级程序设计(第三版)学习笔记6、7章


Posted in Javascript onMarch 11, 2016

第6章,面向对象的程序设计

对象:

1、数据属性

configurable,表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为true

enumerbale,表示能否通过for-in访问属性,默认true

ƒwritable,表示能否修改属性值,默认true

„value,数据存储位置,默认undefined

修改默认属性特性:Object.defineProperty(),接收三个参数:属性所在对象,属性名,描述符对象,描述符对象属性必须是:configurable、enumerable、writable、value

例:

var obj = {};
Object.defineProperty(obj,”name”,{
writable:true,
value:”nihao”
});

2、访问器属性

configurable,表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为true

 enumerbale,表示能否通过for-in访问属性,默认true

get,读取属性时调用,默认undefined

„set,写入属性时调用,默认undefined

修改必须通过Object.defineProperty()

例:

var obj = {
_year:2004,
edition:1
}
Object.defineProperty(book,”year”,{
get:function(){
return this._year;
},
set:function(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition += newValue ? 2004;
}
}
});
book.year = 2005;
alert(book.edition); //2

定义多个属性:Object.defineProperties(),接收两个对象,一是要修改和添加属性的兑现,第二个对象属性与第一个对象要修改或添加的属性一一对应,支持的浏览器:IE9+,FireFox4+,Safari5+,Opera12+,chrome

读取属性:Object.getOwnPropertyDescriptor(),接收两个参数,属性所在对象,要读取描述符的属性名称,支持的浏览器:IE9+,FireFox4+,Safari5+,Opera12+,chrome

创建对象:

工厂模式:

function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“g”,29);

构造函数模式:

function Person(name,age){
this.name = name;
this.age = age;
this.sayName() = function(){
alert(this.name);
};
}
var person = new Person(“g”,28);

两种模式区别:

构造函数模式中不需要显示创建对象,对this直接赋值,没有返回语句

构造函数名首字母必须大写,必须使用new操作符创建新实例

原型模式

创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法,换句话就是,prototype就是通过函数创建的对象的原型对象,好处在于可以是所有实例共享相同的属性和方法。

isPrototypeOf(),个人理解就是可以用以判断某个实例的原型是否与当前原型相同

例:

Person.prototype.isPrototypeOf(person1); //true

Object.getPrototypeOf(),可以返回某个实例的原型,支持的浏览器IE9+,Firefox3.5+,Safari5+,Opera12+,chrome

注:访问对象属性名时会进行一次搜索,先在实例对象搜索,不存在则到当前对象的原型对象去搜索。

注:实例中的属性若与原型对象中的属性一样,则会屏蔽原型对象的属性,与上一条刚好可以对的上

hasOwnProperty()方法可以确定某个属性是否来自实例,不是来自实例,则返回false,否则返回true

在实例上调用delete时,只会删除实例上的属性名,并不会删除原型的属性

例:

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
alert(this.name);
}
var per1 = new Person();
var per2 = new Person();
per1.name = "Greg";
alert(per1.name); //"Greg" 来自实例
alert(per2.name); //"Nicholas"
delete per1.name;
alert(per1.name); //"Nicholas" 来自原型
delete per1.name;
alert(per1.name); //"Nicholas"

注:Object.getOwnPropertyDescriptor()方法只能用于实例属性,要取得原型属性描述符,必须直接在原型对象上调用本方法

in操作符:只有当属性在实例对象中或者在原型对象中时,返回true

例:

alert(“name” in Person); //true
alert(“name” in per1); //true

同时使用in和hasOwnProperty可以确定该属性是存在原型中,还是实例中

Object.keys()方法:接收一个对象作为参数,返回所有可枚举的属性组成的字符串数组

Object.getOwnPropertyNames()方法:接收一个对象,返回所有属性组成的字符串数组,无论是否可枚举

更简单的原型语法:

使用上述方法实在太麻烦了,更经常使用的是以下方法:使用对象字面量

Person.prototype = {
name : “Nicholas”,
age : 29
sayName = function(){
alert(this.name);
}
}

不过,此方法,相当于重写了整个prototype对象,将导致constructor属性不再指向Person而是指向Object,虽然instanceof还是会返回正确的结果,但通过constructor已经不能确定对象类型了。

var per = new Person();
alert(per instanceof Object); //true
alert(per instanceof Person); //true
alert(per constructor Object); //true
alert(per constructor Person); //false

若constructor真的很重要,可以如下设置

Person.prototype = {
constructor:Person,
name : “Nicholas”,
age : 29
sayName = function(){
alert(this.name);
}
}

以上写法会使constructor的enumerable特性被设置为true,默认情况下原生的是false的,在兼容ECMAScript5的浏览器可以使用Object.defineProperty()进行设置

Object.defineProperty(Person.prototype,”constructor”,{
enumerable:false,
value:Person
});

注:重写原型对象,将会切断现有原型与任何之前已经存在的对象实例之间的联系

继承(难度较大,需再仔细研究)

使用原型链来实现

子类型要覆盖超类的方法,应该将给原型添加方法的代码放在替换原型之后,

注:通过原型链实现继承时,不能使用对象字面量创建原型方法,否则会重写原型链

借用构造函数

组合继承

原型式继承,Object.creat();接收两个参数:一是用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象

例:Object.creat(person,{name:{value:”greg”}});

寄生式继承

寄生组合式继承

第7章,函数表达式

创建方式:

1、函数声明,可以函数声明提升,就是可以把使用函数的语句放在函数声明之前

function funName(arg0,arg1){
//函数体
}

2、函数表达式,不能进行函数提升,也就是无法在函数创建前使用函数,在这种情况下创建的函数称为匿名函数,有时也叫拉姆达函数

var funName = function(arg0,arg1){
//函数体
}

严格模式下无法使用arguments.callee来实现递归,可以使用如下方式实现递归:

var factorial = (function f(num){
if(num <= 1){
return 1;
}else{
return num * f(num - 1);
}
});

闭包(难度也不小)

闭包指有权访问另一个函数作用域中的变量的函数,闭包,也是一个函数

创建闭包的常见方式是在一个函数内部创建另一个函数

闭包只能取得包含函数即外部函数中任何变量的最后一个值。下例可以清晰说明问题

例:

function createFuncrions(){
var result = new Array();
for(var i = 0;i < 10;i++){
result[i] = function(){
return i;
}
}
return result;
}
var re = createFuncrions();
alert(re[1](2));

每个函数返回的都将是10,而不是如预期般返回对应的索引值,因为createFuncrions函数最后返回时I = 10,此时每个函数都引用保存着变量i的同一个对象,所以在每个函数内部i都是10,可以使用如下方法强制闭包返回预期效果:

function createFuncrions(){
var result = new Array();
for(var i = 0;i < 10;i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
var re = createFuncrions();
alert(re[2]());

每一个都会返回各自的索引值

模仿块级作用域

使用匿名函数可以模仿块级作用域:

(function(){
alert("test"); //块级作用域,没有使用圆括号将function包起来将会出错
})();

使用闭包和私有变量的明显不足之处在于,会在作用域链中多查找一个层次,在一定程度上影响查找速度

函数中定义的变量可以在一定程度上称为私有变量,通过函数可以模拟出私有变量,静态私有变量

增强模块模式:

var singleton = function(){
//private arg and private method
var privateVariable = 10;
function privateFunction(){
return false;
}
//create obj
var obj = new Object();
obj.publicProperty = true;
obj.publicFunction = function(){
privateVariable ++;
return privateFunction();
};
return obj;
}();
alert(typeof singleton);
alert(singleton.publicProperty);
alert(singleton.publicFunction());

以上内容是小编给大家介绍的JavaScript高级程序设计(第三版)学习笔记6、7章,希望对大家有所帮助!

Javascript 相关文章推荐
select 控制网页内容隐藏于显示的实现代码
May 25 Javascript
javascript实现简单的Map示例介绍
Dec 23 Javascript
js获取判断上传文件后缀名的示例代码
Feb 19 Javascript
jquery中load方法的用法及注意事项说明
Feb 22 Javascript
JavaScript中捕获与冒泡详解及实例
Feb 03 Javascript
原生js仿浏览器滚动条效果
Mar 02 Javascript
JS基于ES6新特性async await进行异步处理操作示例
Feb 02 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
Feb 27 Javascript
Vue 权限控制的两种方法(路由验证)
Aug 16 Javascript
layui table 获取分页 limit的方法
Sep 20 Javascript
微信小程序 自定义弹窗实现过程(附代码)
Dec 05 Javascript
JS前端宏任务微任务及Event Loop使用详解
Jul 23 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
Mar 11 #Javascript
Angularjs中使用Filters详解
Mar 11 #Javascript
使用jquery.qrcode.min.js实现中文转化二维码
Mar 11 #Javascript
JavaScript制作简单的日历效果
Mar 10 #Javascript
js滑动提示效果代码分享
Mar 10 #Javascript
js实现页面跳转的五种方法推荐
Mar 10 #Javascript
js实现页面跳转的五种方法推荐
Mar 10 #Javascript
You might like
做个自己站内搜索引擎
2006/10/09 PHP
PHP XML备份Mysql数据库
2009/05/27 PHP
谈谈新手如何学习PHP 默默经典版本
2009/08/04 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
php使用fopen创建utf8编码文件的方法
2014/10/31 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
2016/05/28 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
Javascript的并行运算实现代码
2010/11/19 Javascript
Kendo Grid editing 自定义验证报错提示的解决方法
2016/11/18 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
对于js垃圾回收机制的理解
2017/09/14 Javascript
关于vuejs中v-if和v-show的区别及v-show不起作用问题
2018/03/26 Javascript
layui实现tab的添加拒绝重复的方法
2019/09/04 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
将Vue组件库更换为按需加载的方法步骤
2020/05/06 Javascript
原生js实现照片墙效果
2020/10/13 Javascript
[49:08]FNATIC vs Infamous 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
Python实现基于权重的随机数2种方法
2015/04/28 Python
Python 编码Basic Auth使用方法简单实例
2017/05/25 Python
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
python多线程socket编程之多客户端接入
2017/09/12 Python
Python 找到列表中满足某些条件的元素方法
2018/06/26 Python
Django的性能优化实现解析
2019/07/30 Python
3分钟看懂Python后端必须知道的Django的信号机制
2020/07/26 Python
Ryderwear澳洲官网:澳大利亚高端健身训练装备品牌
2018/09/18 全球购物
澳大利亚婴儿、幼儿和儿童在线设计师商店:Smooch Baby
2019/02/16 全球购物
如果NULL和0作为空指针常数是等价的,那我到底该用哪一个
2014/09/16 面试题
介绍一下Transact-SQL中SPACE函数的用法
2015/09/01 面试题
计算机专业学生求职信分享
2013/12/15 职场文书
总经理任命书范本
2014/06/05 职场文书
开展批评与自我批评发言材料
2014/10/17 职场文书
单位工资证明范本
2015/06/12 职场文书
《青山不老》教学反思
2016/02/22 职场文书
导游词之广州陈家祠
2019/10/21 职场文书
python实现的人脸识别打卡系统
2021/05/08 Python