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 相关文章推荐
jquery attr 设定src中含有&amp;(宏)符号问题的解决方法
Jul 26 Javascript
解析JavaScript中的不可见数据类型
Dec 02 Javascript
node中socket.io的事件使用详解
Dec 15 Javascript
JS解析XML文件和XML字符串详解
Apr 17 Javascript
AngularJS基础 ng-hide 指令用法及示例代码
Aug 01 Javascript
Jquery实现上下移动和排序代码
Oct 17 Javascript
JS比较两个数值的大小实例
Nov 25 Javascript
JS实现匀加速与匀减速运动的方法示例
Sep 04 Javascript
JS处理一些简单计算题
Feb 24 Javascript
详解各版本React路由的跳转的方法
May 10 Javascript
详解Vuex下Store的模块化拆分实践
Jul 31 Javascript
在Vue项目中,防止页面被缩放和放大示例
Oct 28 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
全国FM电台频率大全 - 19 广东省
2020/03/11 无线电
php获取淘宝分类id示例
2014/01/16 PHP
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php结合md5的加密解密算法实例
2016/09/30 PHP
js option删除代码集合
2008/11/12 Javascript
JQuery触发radio或checkbox的change事件
2012/12/18 Javascript
javascript实现十秒钟后注册按钮可点击的方法
2015/05/13 Javascript
jQuery与JS加载事件用法分析
2016/09/04 Javascript
利用Node.JS实现邮件发送功能
2016/10/21 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
初学者AngularJS的环境搭建过程
2017/10/27 Javascript
Vue使用zTree插件封装树组件操作示例
2019/04/25 Javascript
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
Python and、or以及and-or语法总结
2015/04/14 Python
利用python画一颗心的方法示例
2017/01/31 Python
Python正确重载运算符的方法示例详解
2017/08/27 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
2017/12/14 Python
详解Python 实现元胞自动机中的生命游戏(Game of life)
2018/01/27 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
Python3 使用pillow库生成随机验证码
2019/08/26 Python
python3 deque 双向队列创建与使用方法分析
2020/03/24 Python
pandas使用之宽表变窄表的实现
2020/04/12 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
2020/06/03 Python
Pandas的数据过滤实现
2021/01/15 Python
银行金融服务方案
2014/06/11 职场文书
商务英语专业求职信
2014/06/26 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
副校长个人对照检查材料思想汇报
2014/10/04 职场文书
未婚证明书模板
2014/10/08 职场文书
2014年乡镇党建工作总结
2014/11/11 职场文书
公司行政主管岗位职责
2015/04/09 职场文书
活动新闻稿范文
2015/07/17 职场文书
2019预备党员转正申请书模板2篇!
2019/08/07 职场文书
python模板入门教程之flask Jinja
2022/04/11 Python
PostgreSQL出现死锁该如何解决
2022/05/30 PostgreSQL