JavaScript | Objects 对象(2)

25 篇文章 1 订阅
20 篇文章 0 订阅

介绍JavaScript中的Objects对象的语法及相关特性。




Symbol 类型

“Symbol”值是一种表示唯一的标识符,用于创建对象的“隐藏”属性,防止他人编写代码引用自己的脚本时产生无意的冲突,导致访问或者重写这些属性。

let id = Symbol();      // id是Symbol的一个实例化对象
let id1 = Symbol("id"); // Symobol()内可以添加对对象的描述
let id2 = Symbol("id"); // 与id1一样,描述都为”id“

alert(id1 == id2);      // false

如果想要打印描述,不能直接使用变量名,而需要显式调用toString()方法。

想要在object字面量中使用Symbol,需要使用方括号。

let id = Symbol("ID");

let user = {
  name: "John",
  [id]: 123
};

Symbol 在 for…in 中会被跳过,在 Object.assgin 中会被复制。

Symbol 不是完全隐藏的,有内置方法可以获取。

全局 Symbol

JavaScript ES6 提出的 Symbol 存在一个全局 symbol 注册表。使用 Symbol.for(key) 可以在注册表中创建或读取 Symbol。

该调用会检查全局注册表,如果有一个描述为 key 的 Symbol,则返回该 Symbol,否则将创建一个新 Symbol(Symbol(key)),并通过给定的 key 将其存储在注册表中。

let id = Symbol.for("id");      // 如该 Symbol 不存在,则创建它

let idAgain = Symbol.for("id"); // 再次读取

alert( id === idAgain );        // 两者相同
反向调用

Symbol.for(key)使用名称返回一个symbol变量。
Symbol.keyFor(sym)使用symbol变量返回一个名称。

系统 Symbol

JavaScript 内部还留有一些系统Symbol,我们可以使用它们来微调对象的各个方面。

// 暂略


对象方法

创建对象方法的几种方式:

// 1. 直接赋值
user.sayHi = function() {
  alert("Hello!");
};

// 2. 先声明后赋值
function sayHi() {
  alert("Hello!");
};

user.sayHi = sayHi;

// 3. 对象内赋值
let user = {
  sayHi: function() {
    alert("Hello");
  }
};

// 4. 方法简写
let user = {
  sayHi() {
    alert("Hello");
  }
};

一般来说3与4较为正常,而4在绝大部分情况下都与3没有区别。故推荐使用第4种方法。


“this”

JavaScript中的“this”关键字与其他大多数编程语言不太相同。

this可以用于任何函数而不会报语法错误。

function sayHi() {
  alert( this.name );
}

因为this在运行时才求值,其值由调用该函数的“.”点之前的对象决定。

let user = { name: "John" };
let admin = { name: "Admin" };

function sayHi() {
  alert( this.name );
}

user.f = sayHi;
admin.f = sayHi;
// 函数在两个对象之间共用

user.f();     // John  (this == user)
admin.f();    // Admin  (this == admin)

admin['f'](); // Admin(使用方括号亦可)

在没有任何对象的情况下,严格模式的this等于undefined,这时候如果访问属性则会出错;非严格模式的this将会是全局对象,即浏览器窗口。

我们不应该在没有对象的情况下调用this,这一般是错误的。

其他:

  • 箭头函数没有this,在其内部访问会取得来自外部的this值,所以不适合使用箭头函数定义对象方法。
  • 更多细节在遇到问题时请善用搜索引擎解决。

原始值转换

本小节以下内容从原文摘抄。(因为我不知道用不用的上)

对象到原始值的转换,是由许多内置函数和操作符自动调用的,这些函数使用一个原始值作为返回值的。

它有三种类型(暗示):

  • string”(对于 alert 和其他字符串转换)
  • number”(对于 maths)
  • default”(少数操作)

规范明确描述了哪个操作符使用哪个暗示。极少数操作者“不知道期望什么”并使用 “default” 暗示。通常对于内置对象,"default" 暗示的处理方式与 “number” 相同,因此在实践中最后两个通常合并在一起。

转换算法:

  1. 调用 obj[Symbol.toPrimitive](hint) 如果这个方法存在的话,
  2. 否则如果暗示是 “string
    • 尝试 obj.toString()obj.valueOf(),无论哪个存在。
    • 否则,如果暗示 “number” 或者 “default”
      尝试 obj.valueOf()obj.toString(),无论哪个存在。

在实践中,为了记录或调试目的,仅实现 obj.toString() 作为“全捕获”方法通常就够了,这样所有转换都能返回一种“人类可读”的对象表达形式。


构造函数

JavaScript早期时候虽然没有“类”的概念,但我们可以借助构造函数来达到我们相似的效果,实现对象结构的复用。

在现代JavaScript中已经有class语法了,其本质仍然是一种函数。

构造函数在技术上与一般的函数没有区别,但我们约定:

  1. 大写字母开头
  2. 只能使用new操作符执行

例子:

function User(name) {
  // this = {};(隐式创建)
  this.name = name;
  this.isAdmin = false;
  this.sayHi = new function() {
    alert("Hello");
  };  // <-- 不要漏了这个分号
  // return this;(隐式返回)
}
let Haze = new User("Haze");

// 结构等价于
let user = {
  name: "Haze",
  isAdmin: false,
  sayHi: new function() {
    alert("hello");
  }
};

new 操作符

上面的例子中,隐式创建空对象与隐式返回this都是new的作用。

在函数内部,我们可以使用new.target属性来检查该函数被调用时是否使用了new操作符:

  • new,返回该函数(即 function Func { ... }
  • 不带 new,则返回 undefined

由此可以延伸出一个小trick(但不推荐使用,因为不利于阅读):

function User(name) {
  if (!new.target) {          // 如果没有运行 new
    return new User(name);    // 自动补上 new
  }
  this.name = name;
}

let john = User("John");
let john = new User("John");  // 相同

对于以下对象,我们建议使用其他方法代替使用 new 创建对象:

符号替代
{}new Object()
“”new String()
0new Number()
falsenew Boolean()
[]new Array()
/()/new RegExp()
function (){}new Function()

构造函数 return 规则

一般来说都让它隐式返回this,如果显式return,则有以下规则:

  • 如果返回一个对象,则返回该对象,不返回this
  • 如果返回其他东西,则忽略,仍然返回this

其他

  • JavaScript 为我们内置了许多常用的对象的构造函数,如日期Date、集合Set以及数组Array

  • 当构造函数没有参数时,语法上是支持省略括号的:

    let user = new User;  // 等价于 new User();
    

    但从代码风格角度上并不推荐这么做。




更多内容

点击返回个人笔记导航?

访问我的github笔记⭐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值