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 相关文章推荐
经常用的图片在容器中的水平垂直居中实例
Jun 10 Javascript
DOM节点深度克隆函数cloneNode()用法实例
Jan 12 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
Apr 16 Javascript
javascript清空table表格的方法
May 14 Javascript
在JavaScript中使用对数Math.log()方法的教程
Jun 15 Javascript
jquery插件pagination实现无刷新ajax分页
Sep 30 Javascript
详解JavaScript基于面向对象之创建对象(2)
Dec 10 Javascript
微信小程序getPhoneNumber获取用户手机号
Sep 29 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
Dec 26 Javascript
详解各版本React路由的跳转的方法
May 10 Javascript
node.js使用express框架进行文件上传详解
Mar 03 Javascript
vue-路由精讲 二级路由和三级路由的作用
Aug 06 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
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
php循环table实现一行两列显示的方法
2015/06/04 PHP
phalcon框架使用指南
2016/02/23 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
2016/06/30 PHP
Mac下php 5升级到php 7的步骤详解
2017/04/26 PHP
json的前台操作和后台操作实现代码
2012/01/20 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
2014/05/12 Javascript
JavaScript获得url所有参数键值表的方法
2015/03/21 Javascript
JavaScript作用域示例详解
2016/07/07 Javascript
AngularJs ng-route路由详解及实例代码
2016/09/14 Javascript
JS判断微信扫码的方法
2017/08/07 Javascript
Node.js利用断言模块assert进行单元测试的方法
2017/09/28 Javascript
基于 flexible 的 Vue 组件:Toast -- 显示框效果
2017/12/26 Javascript
JS面试题大坑之隐式类型转换实例代码
2018/10/14 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
javascript 构建模块化开发过程解析
2019/09/11 Javascript
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
ES6 Object.assign()的用法及其使用
2020/01/18 Javascript
vue 解决mintui弹窗弹起来,底部页面滚动bug问题
2020/11/12 Javascript
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
浅谈Python单向链表的实现
2015/12/24 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
python3实现随机数
2018/06/25 Python
Django 实现前端图片压缩功能的方法
2019/08/07 Python
python飞机大战pygame游戏框架搭建操作详解
2019/12/17 Python
优衣库澳大利亚官网:UNIQLO澳大利亚
2017/01/18 全球购物
Marc Jacobs彩妆官网:Marc Jacobs Beauty
2017/07/03 全球购物
Antler英国官网:购买安特丽行李箱、拉杆箱
2019/08/25 全球购物
质量月活动总结
2014/08/26 职场文书
2015年综治维稳工作总结
2015/04/07 职场文书
宾馆卫生管理制度
2015/08/06 职场文书
python如何做代码性能分析
2021/04/26 Python
Html5大屏数据可视化开发的实现
2021/06/11 HTML / CSS