JS 对象生命周期的秘密( 四 )

默认情况下,每个人都可以向该对象添加新属性
var superImportantObject = { property1: "some string", property2: "some other string"};superImportantObject.anotherProperty = "Hei!";console.log(superImportantObject.anotherProperty); // Hei!Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性 。
var superImportantObject = { property1: "some string", property2: "some other string"};Object.preventExtensions(superImportantObject);superImportantObject.anotherProperty = "Hei!";console.log(superImportantObject.anotherProperty); // undefined这种技术对于“保护”代码中的关键对象非常方便 。JS 中还有许多预先创建的对象,它们都是为扩展而关闭的,从而阻止开发人员在这些对象上添加新属性 。这就是“重要”对象的情况,比如XMLHttpRequest的响应 。浏览器供应商禁止在响应对象上添加新属性
var request = new XMLHttpRequest();request.open("GET", "https://jsonplaceholder.typicode.com/posts");request.send();request.onload = function() { this.response.arbitraryProp = "我是新添加的属性"; console.log(this.response.arbitraryProp); // undefined};这是通过在“response”对象上内部调用Object.preventExtensions来完成的 。您还可以使用Object.isExtensible方法检查对象是否受到保护 。如果对象是可扩展的,它将返回true:
var superImportantObject = { property1: "some string", property2: "some other string"};Object.isExtensible(superImportantObject) && console.log("我是可扩展的");如果对象不可扩展的,它将返回false:
var superImportantObject = { property1: "some string", property2: "some other string"};Object.preventExtensions(superImportantObject);Object.isExtensible(superImportantObject) || console.log("我是不可扩展的!");当然,对象的现有属性可以更改甚至删除
var superImportantObject = { property1: "some string", property2: "some other string"};Object.preventExtensions(superImportantObject);delete superImportantObject.property1;superImportantObject.property2 = "yeees";console.log(superImportantObject); // { property2: 'yeees' }现在,为了防止这种操作,可以将每个属性定义为不可写和不可配置 。为此,有一个方法叫Object.defineProperties 。
var superImportantObject = {};Object.defineProperties(superImportantObject, { property1: { configurable: false, writable: false, enumerable: true, value: "some string" }, property2: { configurable: false, writable: false, enumerable: true, value: "some other string" }});或者,更方便的是,可以在原始对象上使用Object.freeze:
var superImportantObject = { property1: "some string", property2: "some other string"};Object.freeze(superImportantObject);Object.freeze工作方式与Object.preventExtensions相同,并且它使所有对象的属性不可写且不可配置 。唯一的缺点是“Object.freeze”仅适用于对象的第一级:嵌套对象不受操作的影响 。
class
有大量关于ES6 类的文章,所以在这里只讨论几点 。JS是一种真正的面向对象语言吗?看起来是这样的,如果咱们看看这段代码
class Person { constructor(name) { this.name = name; } greet() { console.log(`Hello ${this.name}`); }}语法与Python等其他编程语言中的类非常相似:
class Person: def __init__(self, name): self.name = name def greet(self): return 'Hello' + self.name或 php
class Person { public $name;public function __construct($name){ $this->name = $name; } public function greet(){ echo 'Hello ' . $this->name; }}ES6中引入了类 。但是在这一点上,咱们应该清楚JS中没有“真正的”类 。一切都只是一个对象,尽管有关键字class,“原型系统”仍然存在 。新的JS版本是向后兼容的,这意味着在现有功能的基础上添加了新功能,这些新功能中的大多数都是遗留代码的语法糖 。
总结
JS中的几乎所有东西都是一个对象 。从字面上看 。JS对象是键和值的容器,也可能包含函数 。Object是JS中的基本构建块:因此可以从共同的祖先开始创建其他自定义对象 。然后咱们可以通过语言的内在特征将对象链接在一起:原型系统 。
从公共对象开始,可以创建共享原始“父”的相同属性和方法的其他对象 。但是它的工作方式不是通过将方法和属性复制到每个孩子,就像OOP语言那样 。在JS中,每个派生对象都保持与父对象的连接 。使用Object.create或使用所谓的构造函数创建新的自定义对象 。与new关键字配对,构造函数类似于模仿传统的OOP类 。


推荐阅读