哈哈哈万物皆对象,终于到了js的面向对象篇。

一、属性类型

(1)数据属性

数据属性包含一个数据值的位置,在这个位置可以写入和读取数值,数据属性有四个描述器行为的特性

  • [[Configurable]]:表示能否通过 delete 删除属性而重新定义属性,默认值是ture
  • [[Enumerable]]:表示能否通过 for-in 循环返回该属性,默认值true
  • [[Writable]]:表示能否通过修改属性的值,默认值true
  • [[Value]]:包含这个属性的数据值,默认值true

要修改默认属性的特性,必须使用ECMAScript的Objedt.defineProperty()方法,这个方法接受三个参数:函数所在对象、属性名字和一个描述对象。例

  1. var person = {};
  2. Object.defineProperty(person,"name".{
  3. writable:false,
  4. value:"Nicholas"
  5. });
  6. alert(person.name); //Nicholas
  7. person.name = "Greg";
  8. alert(person.name); //Nicholas

(2)访问器属性

访问器属性包括一对getter和setter函数,在读取访问器属性时,会调用getter函数,这个函数负责返回有效值,写入访问器属性的时候,会调用setter函数并传入新值,这个函数决定如何处理数值,访问器属性有如下4个特性

  • [[Configurable]]:能否通过delete删除属性并进行重新定义,默认值时true
  • [[Enumerable]]:表示能否通过for-in循环返回属性,默认值时true
  • [[Get]]:在读取属性时调用的函数,默认值true
  • [[Set]]:在写入属性时调用的函数,默认值true

访问器属性不能直接定义必须使用Obiect.defineProperty()来定义,例

  1. var book = {
  2. _year: 2004,
  3. edition: 1
  4. };
  5. Object.defineProperty(book,"year", {
  6. get: function(){
  7. return: this._year;
  8. },
  9. set: function(newValue){
  10. if(newValue > 2004){
  11. this._year = newValue;
  12. this.edition += newValue - 2004
  13. }
  14. }
  15. });
  16. var year = 2005;
  17. alert(book.edition); //2

二 创建对象

(1)工厂模式

  1. function createPerson(name, age, job){
  2. var o = new Object()
  3. o.name = name
  4. o.age = age
  5. o.job = job
  6. o.sayName = function(){
  7. alert(this.name)
  8. }
  9. return o
  10. }
  11. var person = createPerson("Greag", 29, "Software Engineer")
  12. person.sayName()

每次调用这个createPerson()都能返回一个三个属性一个方法的,工厂模式虽然解决了多个相似对象的问题,但却没有解决对象识别的问题,于是新的模式就出现了

(2)构造函数模式

  1. function Person(name,age,job){
  2. this.name = name;
  3. this.age = age;
  4. this.job = job;
  5. this.sayName = function(){
  6. alert(this.name)
  7. }
  8. }
  1. var person = new Person("Nic", 22, "Software Engineer")
  2. person.sayName()
  1.  

构造函数虽然好用但并不是没有缺点,就是每个方法都要在实例上创建一遍,因为每定义了一个函数就相当于实例化了一个对象,所以构造函数的定义相当与

  1.  
  1.  
  1. function Person(name,age,job){
  2. this.name = name;
  3. this.age = age;
  4. this.job = job;
  5. this.sayName =new Function(
  6. "alert(this.name)"
  7. ) // 与声明函数在逻辑上是相等的
  8. }
    var person1 = new Person("Greg", 22, "Doctor");
    var person2 = new Person("Nic", 22, "Software Engineer");
  1.  

这样就会导致不同的实例上的同名函数是不同的 alert( person1.sayName == person2.sayName)     //false  创建两个完成相同任务的Function完全没有必要,于是又出现了原型模式

(3)原型模式

我们每创建一个函数都会有一个property(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途就是包含可以由特定的类型的所有实例共享的属性和方法,也就是我们不必在构造函数中添加对象的信息,可以直接添加到原型对象上,

  1. //原型模式
  2. function Person(){}
  3. Person.prototype.name = "Nic"
  4. Person.prototype.age = 22
  5. Person.prototype.sayName = function(){
  6. alert(this.name)
  7. }
  8. var person1 = new Person();
  9. var person2 = new Person();
  10. alert(person1.sayName == person2.sayName) //true

简洁的原型语法

  1. //简洁的原型语法
  2. function Person(){}
  3. Person.prototype = {
  4. name:"Nic",
  5. age:22,
  6. sayName:function(){
  7. alert(this.name)
  8. }
  9. }

原型模式也不是没有缺点,首先他省略了为构造函数传递初始化参数这一环节,结果所有实例在相同的情况下都取得相同的属性值,原型模式最大的问题就是其共享的本质所导致,对于包含引用属性的来说,问题就很突出。例

  1. function Person(){};
  2. Person.prototype = {
  3. constructor: Person,
  4. name: "nic",
  5. age: 23,
  6. friends: ["Court", "shelby"]
  7. }
  8. var person1 = new Person();
  9. var person2 = new Person();
  10. person1.friends.push("Van")
  11. alert(person1.friends) //Court, shelby, Van
  12. alert(person2.friends) //Court, shelby, Van
  13. alert(person1.friends === person2.friends) //true

我们的初衷往往不是这样,这也是我们很少看见有人直接用原型模式的原因。

(4)组合使用构造函数和原型模式

创建自定义类型最常见的方式就是组合使用构造函数模式和原型模式,构造函数定义实例属性,原型模式定义方法和共享属性,例

  1. //组合构造函数模式和原型模式
  2. function Person(name, age, job){
  3. this.name = name,
  4. this.age = age,
  5. this.job = job,
  6. this.friends = ["Court", "Shelby"]
  7. }
  8. Person.prototype = {
  9. constructor: Person,
  10. sayName: function(){
  11. alert(this.name)
  12. }
  13. }
  14. var person1 = new Person("Nic", 23, "Software Engineer")
  15. var person2 = new Person("Greg", 22, "Doctor")
  16. person1.friends.push("Van")
  17. alert(person1.friends) //"Court", "Shelby", "Van"
  18. alert(person2.friends) //"Court", "Shelby"
  19. alert(person1.friends === person2.friends) //false
  20. alert(person1.sayName === person2.sayName) //true

Javascript高级程序设计--读书笔记之面向对象(一)的更多相关文章

  1. Javascript高级程序设计--读书笔记之面向对象(二)

    前面讲了面向对象的封装,这章我们就来说一说继承 1.原型链 实现原型链有一种基本模式,其代码大概如下 <script> function SuperType(){ this.propert ...

  2. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  3. javascript高级程序设计读书笔记----面向对象的程序设计

        创建对象   工厂模式 function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = ...

  4. javascript高级程序设计读书笔记

    第2章  在html中使用javascript 一般都会把js引用文件放在</body>前面,而不是放在<head>里, 目的是最后读取js文件以提高网页载入速度. 引用js文 ...

  5. Javascript高级程序设计读书笔记(第六章)

    第6章  面向对象的程序设计 6.2 创建对象 创建某个类的实例,必须使用new操作符调用构造函数会经历以下四个步骤: 创建一个新对象: 将构造函数的作用域赋给新对象: 执行构造函数中的代码: 返回新 ...

  6. 《JavaScript高级程序设计》笔记:面向对象的程序设计(六)

    面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象. 理解对象 创建自定义对象的最简单的方法就是创建一个Object的实例,然后再为它添加属性和方法.例 ...

  7. JavaScript高级程序设计 读书笔记

    第一章 JavaScript 简介 第二章 Html中使用JavaScript 第三章 基本概念 第四章 变量,作用域,内存 第五章 引用类型 第六章 面向对象 第七章 函数表达式 第八章 BOM 第 ...

  8. JavaScript高级程序设计-读书笔记(7)

    第22章 高级技巧 1.高级函数 (1)安全的类型检测 在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串. ...

  9. JavaScript高级程序设计-读书笔记(2)

    第6章 面向对象的程序设计 创建对象 1.最简单方式创建Object的实例,如 var person = new Object(); person.name = “Greg”; person.age ...

随机推荐

  1. elementUI table宽度自适应fit

    :fit='true' 或者直接为 fit

  2. Hibernate4教程六:性能提升和二级缓存

    抓取策略(fetching strategy)是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略.抓取策略可以在O/R映射的元数 ...

  3. layui table 中固定列的行高和table行高不一致

    解决方法:只需在done回调函数执行以下方法 done: function(res, curr, count){ $(".layui-table-main tr").each(fu ...

  4. IPv6 关于路由器配置静态IPv6路由的命令

    今天在学习路由器配置ipv6 的时候遇到了一点疑惑 一条命令为:ipv6 route FE80:0202::/32 serail 0/1 201 一条命令为:ipv6 route FE80:0202: ...

  5. 【串线篇】SpringMvc框架乱码

    提交的数据可能有乱码: * 请求乱码: *      GET请求:改server.xml:在8080端口处URIEncoding="UTF-8" *      POST请求: * ...

  6. 每天一个linux命令:file(11)

    file file命令用来探测给定文件的类型.file命令对文件的检查分为文件系统.魔法幻数检查和语言检查3个过程. 格式 file [选项] [参数] 参数选项 参数 备注 -b 列出辨识结果时,不 ...

  7. NVMe SSD是什么?

    https://blog.51cto.com/alanwu/1766945 一直对闪存存储关注的朋友对NVMe SSD一定非常熟悉,NVMe SSD是现如今性能最好的存储盘.这种高性能盘在互联网领域已 ...

  8. QByteArray和十六进制的QString(char*)相互转换

    #include <QCoreApplication> #include <QDebug> #include <QDataStream> QByteArray He ...

  9. OC学习篇之---对象的拷贝

    在前一篇文章中我们说到了如何解决对象的循环引用问题:http://blog.csdn.net/jiangwei0910410003/article/details/41926369,这一篇文章我们就来 ...

  10. 系统的重要文件/etc/inittab被删除了--急救办法!

    如果在生产环境中,系统的重要文件/etc/inittab被删除了(系统还没重启,崩溃前),不要急,下面告诉你该如何处理.1.模拟误删除文件[root@localhost ~]# rm -rf /etc ...