JS基础总结

2018-10-01  本文已影响0人  黑色的五叶草

(以下内容,参考自阮一峰es5)

  1. console.log(对象)时,页面弹出的就是[object,Object] 它代表什么?
alert会调用变量的toString方法,toString会生成[object classname]的结果,
第一个object表示变量是对象,不是值类型,classname表示该对象的类名。
[object Object]前面一个object表示他是对象,后面一个Object表示它是Object类的。
  1. 函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域
  2. 函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递(passes by value)。这意味着,在函数体内修改参数值,不会影响到函数外部。
var p = 2;

function f(p) {
  p = 3;
}
f(p);

p // 2

如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。也就是说,传入函数的原始值的地址,因此在函数内部修改参数,将会影响到原始值。

var obj = { p: 1 };

function f(o) {
  o.p = 2;
}
f(obj);

obj.p // 2

注意,如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值。(本质上是替换了地址)

var obj = [1, 2, 3];

function f(o) {
  o = [2, 3, 4];
}
f(obj);

obj // [1, 2, 3]
  1. Object.keys
var obj = {
  p1: 123,
  p2: 456
};
Object.keys(obj) // ["p1", "p2"]
var arr = ['a', 'b', 'c'];

Object.keys(arr)
// ["0", "1", "2"]
var arr = ['a', 'b', 'c'];

arr['0'] // 'a'
arr[0] // 'a'
  1. 对象有两种读取成员的方法:点结构(object.key)和方括号结构(object[key])。但是,对于数值的键名,不能使用点结构。
var arr = [1, 2, 3];
arr.0 // SyntaxError
  1. 数组遍历方法:
var a = [1, 2, 3];

// for循环
for(var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

// while循环
var i = 0;
while (i < a.length) {
  console.log(a[i]);
  i++;
}

// 反向遍历,从最后一位开始
var l = a.length;
while (l--) {
  console.log(a[l]);
}
var colors = ['red', 'green', 'blue'];
colors.forEach(function (color) {
  console.log(color);
});
// red
// green
// blue
var a = [1, 2, 3];
a.foo = true;

for (var key in a) {
  console.log(key);
}
// 0
// 1
// 2
// foo
  1. 数组的空位
var a = [1, 2, 3];
delete a[1];

a[1] // undefined
a.length // 3
var a = [, , ,];

a.forEach(function (x, i) {
  console.log(i + '. ' + x);
})
// 不产生任何输出

for (var i in a) {
  console.log(i);
}
// 不产生任何输出

Object.keys(a)
// []
var a = [undefined, undefined, undefined];

a.forEach(function (x, i) {
  console.log(i + '. ' + x);
});
// 0. undefined
// 1. undefined
// 2. undefined

for (var i in a) {
  console.log(i);
}
// 0
// 1
// 2

Object.keys(a)
// ['0', '1', '2']
  1. 类数组对象:
// arguments对象
function args() { return arguments }
var arrayLike = args('a', 'b');

arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false

// DOM元素集
var elts = document.getElementsByTagName('h3');
elts.length // 3
elts instanceof Array // false

// 字符串
'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false
  1. 加法运算符是在运行时决定,到底是执行相加,还是执行连接。也就是说,运算子的不同,导致了不同的语法行为,这种现象称为“重载”(overload)。由于加法运算符存在重载,可能执行两种运算,使用的时候必须很小心。
'3' + 4 + 5 // "345"
 3 + 4 + '5' // "75"
  1. 对象的相加:必须先转成原始类型的值,然后再相加。
var obj = { p: 1 };
obj + 2 // "[object Object]2"

操作顺序:
1.首先,自动调用对象的valueOf方法,返回对象自身

 var obj = { p: 1 };
 obj.valueOf() // { p: 1 }

2.再自动调用对象的toString方法,将其转为字符串。

var obj = { p: 1 };
obj.valueOf().toString() // "[object Object]"
var obj = {
  valueOf: function () {
    return 1;
  },
  toString: function () {
    return 'hello';
  }
};

obj + 2 // 3

由于valueOf方法直接返回一个原始类型的值,所以不再调用toString方法。

  1. 强制转换_Number()方法,参数是对象时转型过程:
    (1). 调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。
    (2). 如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
    (3). 如果toString方法返回的是对象,就报错。

    var obj = {x: 1};
    Number(obj) // NaN
    
    // 等同于
    if (typeof obj.valueOf() === 'object') {
      Number(obj.toString());
    } else {
      Number(obj.valueOf());
    }
    

    上面代码中,Number函数将obj对象转为数值。背后发生了一连串的操作,首先调用obj.valueOf方法, 结果返回对象本身;于是,继续调用obj.toString方法,这时返回字符串[object Object],对这个字符串使用Number函数,得到NaN。

    默认情况下,对象的valueOf方法返回对象本身,所以一般总是会调用toString方法,而toString方法返回对象的类型字符串(比如[object Object])。所以,会有下面的结果。

    Number({}) // NaN
    

    如果toString方法返回的不是原始类型的值,结果就会报错。

    var obj = {
      valueOf: function () {
        return {};
      },
      toString: function () {
        return {};
      }
    };
    
    
    Number(obj)
    // TypeError: Cannot convert object to primitive value
    

    valueOf和toString方法,都是可以自定义的。

    Number({
      valueOf: function () {
        return 2;
      },
      toString: function () {
        return 3;
      }
    })
    // 2
    
  2. parseIntparseFloatNumber的区别:parseInt、parseFloat是对字符换转换;Number可以对任意类型转换

  3. Number()+运算符转换数值时,null转为数值时为0,而undefined转为数值时为NaN。

  4. Object.prototype.toString()

  1. Array.prototype.slice()方法:
    返回数组的深拷贝
    var arr = ['djf', {a:1,b:2,c:[4,5,6]}, 112];
    var copy = arr.slice();
    console.dir(copy);
    copy[0] = 0;
    console.dir(arr);
    
    slice方法的一个重要应用,是将类似数组的对象转为真正的数组。
    Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
    // ['a', 'b']
    
    Array.prototype.slice.call(document.querySelectorAll("div"));
    Array.prototype.slice.call(arguments);
    
  2. Array.prototype.concat()方法:
  1. String.prototype.concat()方法:
  1. String.prototype.slice()方法:
  1. String.prototype.trim()方法:
    trim方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串。
     '  hello world  '.trim()
     // "hello world"
    
  2. 事件循环
  1. 定时器运行机制:
    setTimeoutsetInterval指定的回调函数,必须等到本轮事件循环的所有同步任务都执行完,才会开始执行。
  1. Promise对象:
  1. 除了时间对象Date。其他对象求值都是先调用valueOf()方法,再调用toString()方法
  2. 页面重流和重绘性能优化
  1. History对象:
上一篇下一篇

猜你喜欢

热点阅读