当前位置: 首页 > news >正文

JavaScript高级程序设计读书分享之8章——8.2创建对象

JavaScript高级程序设计(第4版)读书分享笔记记录

适用于刚入门前端的同志

创建Object的实例

let person = new Object(); 
person.name = "Nicholas"; 
person.age = 29; 
person.job = "Software Engineer"; 
person.sayName = function() { console.log(this.name); 
};

对象字面量     

let Person = {name:'Tom',age:28,job:'Teacher',sayName(){console.log(this.name)}
}
Person.sayName() // Tom

    虽然使用 Object 构造函数或对象字面量可以方便地创建对象,但这些方式也有明显不足:创建具有同样接口的多个对象需要重复编写很多代码。

工厂模式

function createPerson(name,age,job){let o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function(){console.log(this.name)}return o;
}let person1 = createPerson('Tom',28,'Teacher')
let person2 = createPerson('Jerry',18,'Student')
console.log(person1 ) // {name:'Tom',age:28,job:'Teacher',sayName: ƒ ()}
      问题:  这种工厂模式虽 然可以解决创建多个类似对象的问题,但没有解决对象标识问题(即新创建的对象是什么类型)

构造函数模式

function Person(name,age,job){this.name = namethis.age = agethis.job = jobthis.sayName = function(){console.log(this.name)}}let person1 = new Person('Tom',28,'Teacher')
person1.sayName () //Tomlet person2 = new Person('Jerry',18,'Student')
person1.sayName () //Jerry

工厂模式和构造函数模式的区别:

  • 没有显式地创建对象。
  • 属性和方法直接赋值给了 this
  • 没有 return
要创建 Person 的实例,应使用 new 操作符。以这种方式调用构造函数会执行如下操作:
  1. 创建一个新对象;
  2. 将构造函数的作用域赋给新对象(使this指向新对象);
  3. 执行构造函数中的代码(为这个新对象添加属性);
  4. 返回新对象。

问题

        构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍。因此对前面的例子而言,person1 和 person2 都有名为 sayName()的方法,但这两个方 法不是同一个 Function 实例。

解决:
要解决这个问题,可以把函数定义转移到构造函数外部
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; 
} 
function sayName() { console.log(this.name); 
} 
let person1 = new Person("Nicholas", 29, "Software Engineer"); 
let person2 = new Person("Greg", 27, "Doctor"); 
person1.sayName(); // Nicholas 
person2.sayName(); // Greg

原型模式

function Person(){}
Person.prototype.name = 'Tom'
Person.prototype.age = 28
Person.prototype.job = 'Teacher'
Person.prototype.sayName = function(){console.log(this.name)
}let person1 = new Person()
person1.sayName() // Tomlet person2 = new Person()
person1.sayName() // Tomconsole.log(person1.sayName == person2.sayName); // true

理解原型

        无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个 prototype 属性(指向原型对象)。默认情况下,所有原型对象自动获得一个名为 constructor 的属性,指回与之关联的构 造函数。

前面的例子就可以理解为:

Person.prototype.constructor 指向 Person。

console.log(Person.prototype.constructor === Person); // true

         在自定义构造函数时,原型对象默认只会获得 constructor 属性,其他的所有方法都继承自
 Object。每次调用构造函数创建一个新实例,这个实例的内部[[Prototype]](__proto__属性)指针就会被赋值为构造函数的原型对象

console.log(Person.prototype.__proto__ === Object.prototype); // true

 原型层级

        当访问某个实例的属性和方法时,会先在实例上搜索个属性。如果这个属性在实例上存在,所以就不会再搜索原型对象了。而并没有在实例上找到这个属性,所以会继续搜索原型对象并使用定义在原型上的属性。

例子:

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { console.log(this.name); 
}; 
let person1 = new Person(); 
let person2 = new Person(); 
person1.name = "Greg"; 
console.log(person1.name); // "Greg",来自实例
console.log(person2.name); // "Nicholas",来自原型
        只要给对象实例添加一个属性,这个属性就会遮蔽shadow)原型对象上的同名属性,也就是虽然 不会修改它,但会屏蔽对它的访问。不过,使用 delete 操作符可以完全删除实例上的这个属性,从而让标识符解析过程能够继续搜索原型对象。

例子:

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { console.log(this.name); 
}; 
let person1 = new Person(); 
let person2 = new Person(); 
person1.name = "Greg"; console.log(person1.name); // "Greg",来自实例
console.log(person2.name); // "Nicholas",来自原型delete person1.name; 
console.log(person1.name); // "Nicholas",来自原型
hasOwnProperty()方法
        用于确定某个属性是在实例上还是在原型对象上。这个方法是继承自 Object的,会在属性存在于调用它的对象实例上时返回 true,在原型上返回false。
        通过调用 hasOwnProperty()能够清楚地看到访问的是实例属性还是原型属性。
例子:
function Person() {} 
Person.prototype.name = "Nicholas";
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { console.log(this.name); 
};let person1 = new Person(); 
let person2 = new Person(); console.log(person1.hasOwnProperty("name")); // falseperson1.name = "Greg"; 
console.log(person1.name); // "Greg",来自实例
console.log(person1.hasOwnProperty("name")); // true
 hasPrototypeProperty()
属性首先只存在于原型上,所以 hasPrototypeProperty()返回 true。
实例上也有了这个属性,因此 hasPrototypeProperty()返回 false
例子:
// 原型对象还是接上面的let person = new Person(); 
console.log(hasPrototypeProperty(person, "name")); // true person.name = "Greg"; 
console.log(hasPrototypeProperty(person, "name")); // false

Object.keys()

要获得对象上所有可枚举的实例属性

//原型对象接上面的案例let keys = Object.keys(Person.prototype); 
console.log(keys); // "name,age,job,sayName" let p1 = new Person(); 
p1.name = "Rob"; 
p1.age = 31; 
let p1keys = Object.keys(p1); 
console.log(p1keys); // "[name,age]"

Object.getOwnPropertyNames()

如果想列出所有实例属性,无论是否可以枚举,都可以使用

let keys = Object.getOwnPropertyNames(Person.prototype); 
console.log(keys); // "[constructor,name,age,job,sayName]"
Object.getOwnPropertySymbols()

对象迭代

ECMAScript 2017 新增了两个静态方法,Object.values()Object.entries()接收一个对象

示例:

 const o ={foo: 'bar', baz: 1, qux: {} 
}; console.log(Object.values(o)); // ["bar", 1, {}]
console.log(Object.entries((o))); // [["foo", "bar"], ["baz", 1], ["qux", {}]]

http://www.lryc.cn/news/24662.html

相关文章:

  • 关于Could not build wheels for opencv-python-headless, which is...报错的解决方案
  • 【K3s】第1篇 K3s入门级介绍及架构详解
  • Java学习--反射
  • 应用和迭代(名词解释)
  • HTMLCollection 和 NodeList 区别
  • fork()出来一个进程,这个进程的父进程是从哪来的?
  • 结构体内存对齐
  • 【C语言进阶】指针进阶
  • java:Class的isPrimitive方法使用
  • TCP 握手过程 三次 四次
  • windows 下 安裝mysql 5.7.41 (64位) 超简单方式
  • 二叉树——二叉树的最近公共祖先
  • 数据结构与算法基础-学习-14-线性表之串
  • Mac 快捷键
  • 【微服务】-微服务环境搭建
  • IGKBoard(imx6ull)-ADC编程MQ-2烟雾传感器采样
  • 前端二面vue面试题总结
  • 时间API在更新,传奇已经谢幕,但技术永远不死
  • SQL调优指南笔记22:Gathering Diagnostic Data with SQL Test Case Builder
  • 从0开始学python -43
  • Kafka基本原理
  • css3的重点内容
  • 《Roller: Fast and Efficient Tensor Compilation for Deep Learning》
  • 顺丰同城测试开发一面 49min答案,全文7000字,面试总结都在这里了
  • docker启动容器服务之后访问失败
  • GraalVM-云原生时代的JVM(Java)
  • 如何外网登录访问瑞友天翼应用虚拟化系统?——快解析内网端口映射方案
  • 蓝海彤翔执行副总裁张加廷接受【联播苏州】独家专访
  • iOS Airplay Screen Mirroring 同屏技术详解
  • 更新 Python 100道基础入门检测练习题【下篇】(附答案)