JavaScript 备忘笔记

  • ECMAScript 中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。 
  • 可以向 ECMAScript 函数传递任意数量的参数,并且可以通过 arguments 对象来访问这些参数。  
  • 由于不存在函数签名的特性,ECMAScript 函数不能重载。通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。
  • 为了证明参数 对象是按值传递的,我们再看一看下面这个经过修改的例子: 
  • js中是按值传递的
  • function setName(obj) { 
        obj.name = "Nicholas"; 
        obj = new Object(); 
        obj.name = "Greg"; 
        } 
    var person = new Object(); 
    setName(person); 
    alert(person.name); //"Nicholas"
 这个例子与前一个例子的唯一区别,就是在 setName()函数中添加了两行代码:一行代码为 obj 重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的 name 属性。在把 person 传递给 setName()后,其 name 属性被设置为"Nicholas"。然后,又将一个新对象赋给变量 obj,同时将其 name 属性设置为"Greg"。如果 person 是按引用传递的,那么 person 就会自动被修改为指向其 name 属性值 为"Greg"的新对象。但是,当接下来再访问person.name 时,显示的值仍然是"Nicholas"。这说明 即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这 个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
  • 组合使用构造函数模式和原型模式 
创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实 例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本, 但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参 数;可谓是集两种模式之长。下面的代码重写了前面的例子。 
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}
Person.prototype = {
    constructor : Person,
    sayName : function(){
        alert(this.name);
    }
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van”
alert(person2.friends); //"Shelby,Count”
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
在这个例子中,实例属性都是在构造函数中定义的,而由所有实例共享的属性 constructor 和方法 sayName()则是在原型中定义的。而修改了 person1.friends(向其中添加一个新字符串),并不会影响到 person2.friends,因为它们分别引用了不同的数组。 这种构造函数与原型混成的模式,是目前在 ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

  • 数组去重
//js对象实际上是哈希表
let signaling = {};
//利用对象的特性,组织不重复的protocol.message数据到data的"signaling"属性包含的对象数组中data_tem.forEach((o, p, q) => {
    if (!signaling[q[p].protocol + '.' + q[p].message]) {
        signaling[q[p].protocol + '.' + q[p].message] = q[p].protocol + '.' + q[p].message;

  • 尤雨溪:真正会导致上下行解析出问题的 token 有 5 个:括号,方括号,正则开头的斜杠,加号,减号。我还从没见过实际代码中用正则、加号、减号作为行首的情况,所以总结下来就是一句话:一行开头是括号或者方括号的时候加上分号就可以了,其他时候全部不需要。其实即使是这两种情况,在实际代码中也颇为少见。

  • 对象深拷贝
推荐使用框架 lodash 的 _.cloneDeep(value) 方法。
我常用的两种方法:
第一种:
obj = JSON.parse(JSON.stringify(o));
这种方法有弊端,已知一个包含Date()数据时在转换过程中会变成字符串;
第二种:
  //deepCopyvardeepCopy = function(source) {
 var result;
  (source instanceof Array) ? (result = []) : (result = {});

 for (varkey in source) {
    result[key] = (typeof source[key]==='object') ? deepCopy(source[key]) : source[key];
  }
 return result;
};

ES 6 中数组深拷贝:
const a1 = [1, 2];
const a2 = [...a1];

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章