《JavaScript权威指南》中对 typeof 的介绍:typeof 是一元操作符,放在其单个操作数的前面,操作数可以是任意类型。返回值为表示操作数类型的一个字符串。
typeof返回的数据类型有6种,分别是:
1、object,对象类型;
tips:数组使用typeof 会返回object,null 被认为是一个空的对象引用,typeof(null)为object。

2、undefined,未定义类型;
3、string,字符串类型;
4、number,数字类型;
5、boolean,布尔类型;
6、function,函数类型。

综上可以看出,对于数组、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。
toString() 方法返回一个表示该对象的字符串。
每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。
ES5 规范中当 toString 方法被调用的时候,下面的步骤会被执行:
1. 如果 this 值是 undefined,就返回 [object Undefined]
2. 如果 this 的值是 null,就返回 [object Null]
3. 让 O 成为 ToObject(this) 的结果
4. 让 class 成为 O 的内部属性 [[Class]] 的值
5. 最后返回由 "[object " 和 class 和 "]" 三个部分组成的字符串
下面列举使用Object.prototype.toString.call()的几种情况:(标黄较为常用)
1.[object Number]

为什么需要call?
由于Object.prototype.toString()本身允许被修改,像Array、Boolean、Number的toString就被重写过,所以需要调用Object.prototype.toString.call(arg)来判断arg的类型,call将arg的上下文指向Object,所以arg执行了Object的toString方法。至于call,就是改变对象的this指向,当一个对象想调用另一个对象的方法,可以通过call或者apply改变其this指向,将其this指向拥有此方法的对象,就可以调用该方法了。
此处引用Object.prototype.toString.call()原理_年轻的老六的博客-CSDN博客_object.prototype.tostring.call
2.[object String]

3.[object Boolean]

4.[object Undefined]

5.[object Null]

6.[object Object]

7.[object Array]

8.[object Date]

9.[object Error]

10.[object RegExp]

11.[object Function]

12.[object Math]

13.[object JSON]

此处参考博客:call()和apply()方法的区别和详细用法_想你有幸的博客-CSDN博客_call方法和apply的区别是什么
每个函数都包含两个非继承而来的方法:call()方法和apply()方法。call和apply可以用来重新定义函数的执行环境,也就是this的指向;call和apply都是为了改变某个函数运行时的context,即上下文而存在的,换句话说,就是为了改变函数体内部this的指向。
call()和apply()方法的相同点就是这两个方法的作用是一样的。都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向,看个例子:
- function add(a, b) {
- return a + b;
- }
-
- function sub(a, b) {
- return a - b;
- }
-
- console.log(add.call(sub, 2, 1));//3
为什么add.call(sub, 2, 1)的执行结果是3呢,因为call()方法改变了this的指向,使得sub可以调用add的方法,也就是用sub去执行add中的内容,再来看一个例子:
- function People(name, age) {
- this.name = name;
- this.age = age;
- }
-
- function Student(name, age, grade) {
- People.call(this, name, age);
- this.grade = grade;
- }
-
- var student = new Student('小明', 21, '大三');
- console.log(student.name + student.age + student.grade);//小明21大三
在这个例子中,我们并没有给Student的name和age赋值,但是存在这两个属性的值,这还是要归功于call()方法,它可以改变this的指向。
在这个例子里,People.call(this, name, age);中的this代表的是Student,这也就是之前说的,使得Student可以调用People中的方法,因为People中有this.name = name;等语句,这样就将name和age属性创建到了Student中。
总结一句话就是call()可以让括号里的对象来继承括号外函数的属性。
call()和apply()的不同点就是接收参数的方式不同。
this),另一个是参数数组。this),但是传递给函数的参数必须列举出来。即call可以传入多个参数;apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入。
PS:apply()可以将一个数组默认的转换为一个参数列表([param1,param2,param3]转换为param1,param2,param3)。
例:
- var arr1 = [1, 2, 3];
- var arr2 = [4, 5, 6];
- arr1.push.apply(arr1, arr2);
- console.log(arr1);//[ 1, 2, 3, 4, 5, 6 ]