美文网首页
JS中可能被你忽略的几个知识点

JS中可能被你忽略的几个知识点

作者: 酷酷的凯先生 | 来源:发表于2021-04-16 11:24 被阅读0次

String.raw()

String.raw() 是一个模板字符串的标签函数,是用来获取一个模板字符串的原始字符串的,比如说,占位符(例如 ${foo})会被处理为它所代表的其他字符串,而转义字符(例如 \n)不会。

语法:

String.raw(callSite, ...substitutions)
String.raw`templateString`

callSite:一个模板字符串的“调用点对象”。类似{ raw: ['foo', 'bar', 'baz'] }。
...substitutions:任意个可选的参数,表示任意个内插表达式对应的值。
templateString:模板字符串,可包含占位符(${...})。

实例:

String.raw`Hi\n${2+3}!`;  
// 'Hi\n5!',Hi 后面的字符不是换行符,\ 和 n 是两个不同的字符

String.raw `Hi\u000A!`;
// "Hi\u000A!",同上,这里得到的会是 \、u、0、0、0、A 6个字符,
// 任何类型的转义形式都会失效,保留原样输出,不信你试试.length

let name = "Bob";
String.raw `Hi\n${name}!`;
// "Hi\nBob!",内插表达式还可以正常运行

String.raw`t${0}e${1}s${2}t`  
等同于==》
String.raw({ raw: 'test' }, 0, 1, 2);  
// 都会输出 't0e1s2t' 
// 注意这个测试是传入的一个 string 和一个类似数组的对象

String.raw`foo${2 + 3}bar${'Java' + 'Script'}baz`
等同于==》
String.raw({  raw: ['foo', 'bar', 'baz'] }, 2 + 3, 'Java' + 'Script');
// 都会输出 ”foo5barJavaScriptbaz"

Object.freeze

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;
冻结的对象则不能添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。
此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

语法:Object.freeze(obj)
obj:要被冻结的对象

返回值:
表示给定对象是否被冻结的

实例:

冻结对象:
var obj = {
  prop: function() {},
  foo: 'bar'
};

// 新的属性会被添加, 已存在的属性可能会被修改或移除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;

// 作为参数传递的对象与返回的对象都被冻结
// 所以不必保存返回的对象(因为两个对象全等)
var o = Object.freeze(obj);
o === obj; // true
Object.isFrozen(obj); // === true ( isFrozen:判断对象是否被冻结 )

// 现在任何改变都会失效
obj.foo = 'quux'; // 静默地不做任何事
obj.quaxxor = 'the friendly duck';// 静默地不添加此属性

// 在严格模式,如此行为将抛出 TypeErrors
'use strict';
obj.foo = 'sparky';  // throws a TypeError
delete obj.quaxxor;  // 返回true,因为quaxxor属性从来未被添加
obj.sparky = 'arf';  // throws a TypeError
 
// 试图通过 Object.defineProperty 更改属性
// 下面两个语句都会抛出 TypeError.
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });

// 也不能更改原型,下面两个语句都会抛出 TypeError.
Object.setPrototypeOf(obj, { x: 20 })
obj.__proto__ = { x: 20 }


冻结数组:
let a = [0];
Object.freeze(a); // 现在数组不能被修改了

a[0]=1; // fails silently
a.push(2); // fails silently

// 在严格模式,如此行为将抛出 TypeErrors
"use strict"
a[0] = 1;
a.push(2);

浅冻结:
obj1 = {
  internal: {}
};

Object.freeze(obj1);
obj1.internal.a = 'aValue';
console.log(obj1.internal.a); // 'aValue' (这里有点类似 const)

深冻结:
function deepFreeze(obj) {
  // 取回定义在obj上的属性名
  var propNames = Object.getOwnPropertyNames(obj);
  // 在冻结自身之前冻结属性
  propNames.forEach(function(name) {
    var prop = obj[name];
    // 如果prop是个对象,冻结它
    if (typeof prop == 'object' && prop !== null)
      deepFreeze(prop);
  });
  // 冻结自身(no-op if already frozen)
  return Object.freeze(obj);
}
obj2 = {
  internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
console.log( obj2.internal.a ); // undefined

友情提示:
在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 [`TypeError`]
在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回。

Array.prototype.push

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

语法:arr.push(element1, ..., elementN)
elementN:被添加到数组末尾的元素。

返回值:
新的 Arraylength 属性值将被返回。

示例:

将元素添加到数组:
var sports = ["soccer", "baseball"];
var total = sports.push("football", "swimming");

console.log(sports); // ["soccer", "baseball", "football", "swimming"]
console.log(total); // 4

合并两个数组:
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

Array.prototype.push.apply(vegetables, moreVegs);
console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot']
注意:moreVegs 元素太多时不建议使用,push 接受的参数个数有限制

相关文章

网友评论

      本文标题:JS中可能被你忽略的几个知识点

      本文链接:https://www.haomeiwen.com/subject/yklwkltx.html