Comments (34)
1. Object.prototype.toString.call()
每一个继承 Object 的对象都有 toString
方法,如果 toString
方法没有重写的话,会返回 [Object type]
,其中 type 为对象的类型。但当除了 Object 类型的对象外,其他类型直接使用 toString
方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
const an = ['Hello','An'];
an.toString(); // "Hello,An"
Object.prototype.toString.call(an); // "[object Array]"
这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined 。
Object.prototype.toString.call('An') // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call()
常用于判断浏览器内置对象时。
更多实现可见 谈谈 Object.prototype.toString
2. instanceof
instanceof
的内部机制是通过判断对象的原型链中是不是能找到类型的 prototype
。
使用 instanceof
判断一个对象是否为数组,instanceof
会判断这个对象的原型链上是否会找到对应的 Array
的原型,找到返回 true
,否则返回 false
。
[] instanceof Array; // true
但 instanceof
只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true。
[] instanceof Object; // true
3. Array.isArray()
-
功能:用来判断对象是否为数组
-
instanceof 与 isArray
当检测Array实例时,
Array.isArray
优于instanceof
,因为Array.isArray
可以检测出iframes
var iframe = document.createElement('iframe'); document.body.appendChild(iframe); xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1,2,3); // [1,2,3] // Correctly checking for Array Array.isArray(arr); // true Object.prototype.toString.call(arr); // true // Considered harmful, because doesn't work though iframes arr instanceof Array; // false
-
Array.isArray()
与Object.prototype.toString.call()
Array.isArray()
是ES5新增的方法,当不存在Array.isArray()
,可以用Object.prototype.toString.call()
实现。if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
from daily-interview-question.
对于性能问题,我测试几遍的结果 Array.isArray 的性能最好,instanceof 比 toString.call 稍微好了一点点
测试链接: https://jsperf.com/judging-array-type/
对于其中的性能差异的原理,大家可以讨论一下的
from daily-interview-question.
从Stack Overflow扒来的资料:
结论:toString.call和isArray的性能一样差,instanceof稍好,constructor性能最好
优劣我只能看到这么多了。非要咬文嚼字大概就是Array.isArray在老浏览器需要polyfill,然后又跟toString.call一样了。
初次之外看到一个神奇之处,instanceof不能检测来自iframe的数组。就是官方文档上,window.frames[xx].Array构造出来的数组。
from daily-interview-question.
instanceof是判断类型的prototype是否出现在对象的原型链中,但是对象的原型可以随意修改,所以这种判断并不准确。
const obj = {}
obj.__proto__ = Array.prototype
// Object.setPrototypeOf(obj, Array.prototype)
obj instanceof Array // true
from daily-interview-question.
arr.constructor === Array
from daily-interview-question.
但当除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
这里感觉不太清晰。事实上应该不是改变 toString 的上下文,而是改变调用的 toString 方法:
const arr = [1, 2]
arr.toString === Object.prototype.toString // false, 所以两者不同,实际上数组上重写了 toString 方法
const o = {o: 1}
o.toString === Object.prototype.toString // true, 所以对象默认不需要如此调用。但如果将对象的方法改写就不一定了
o.toString = function changedToString() {
return 'haha';
}
o.toString() // 'haha'
Object.prototype.toString.call(o) // '[object Object]'. 发现 Object.prototype.toString 也是可以被改写的...
call
方法的第一个参数会被当作 this
,所以 arr.toString()
与 Object.prototype.toString.call(arr)
并没有改变 this
,而是改变了调用的函数。
from daily-interview-question.
https://www.cnblogs.com/onepixel/p/5126046.html
from daily-interview-question.
typeof 是什么原理呢?
哪位大神给讲讲
typeof 只能检测 基本数据类型,包括boolean、undefined、string、number、symbol,而null ,Array、Object ,使用typeof出来都是Objec。无法检测具体是哪种引用类型。
from daily-interview-question.
Object.prototype.toString.call()
这个方法也不是完全靠谱的啊,
如果遇到对象的属性 Symbol.toStringTag
被改成了"Array"
怎么办啊
应该要加上instanceof
和typeof
三重判断才行
from daily-interview-question.
typeof不能校验object的其他类型,引用类型除了function都不能区分
instanceof不能校验原始值类型
'a' instanceof String
// false
Object.prototype.toString.call()
不能校验自定义类型
function Animal (){}
let a = new Animal()
Object.prototype.toString.call(a)
"[object Object]"
from daily-interview-question.
constructor可以被修改?
from daily-interview-question.
typeof 是什么原理呢?
哪位大神给讲讲typeof 只能检测 基本数据类型,包括boolean、undefined、string、number、symbol,而null ,Array、function、Object ,使用typeof出来都是Objec。无法检测具体是哪种引用类型。
函数的typeof是'function'
from daily-interview-question.
其实还可以用
JSON.stringify
来判断是不是数组
数组转json
是以[
开头,以]
结尾的
from daily-interview-question.
如果真数组的Symbol.toStringTag
属性被修改了,或者__proto__
被修改了,怎么判断?
var realarray=[]
realarray[Symbol.toStringTag]='Function'
realarray.__proto__=Function.prototype
用Array.isArray
判断结果是true
from daily-interview-question.
isArray()不是es6新增吗
from daily-interview-question.
typeof 是什么原理呢?
哪位大神给讲讲
- typeof在判断一些引用类型时会分辨不出具体类型:
-
例如对象和数组;
typeof [1,2,3]; //object
typeof {}; //object -
还有typeof判断String/Array/Boolean/Number等等,都会返回'function',当作是String/Array/Boolean/Number类型的构造函数;
typeof Array; //function Array类型的构造函数
2.实际上js在底层存储变量的时候,会在变量的机器码的低位(1-3位)存储其类型信息,对象用的是000,null的所有机器码(不仅是1-3位)都是0,所以typeof还无法区分object 和 null;
from daily-interview-question.
Object.prototype.toString.call可以识别出所有的数据类型,比如
Object.prototype.toString.call({ }) // "[object Object]"
Object.prototype.toString.call([2,3]) // "[object Array]"
Object.prototype.toString.call('An') // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
instanceof 不能使用在原始类型上,只能用在对象类型上,
left instance right,
如果left的原型链上能找到right的prototype,即left是right的一个实例,如果能找到返回为true,比如
[] instanceof Array //true
,
但是这样写区分不了对象和数组,因为
[] instanceof Object//也返回true
,
原因是所有对象类型的祖宗都是Object
isArray可以用来判断是否是数组,而且可以区分对象
上图解析:
- 原型链就是多个对象通过__proto__连接了起来
- 凡是对象,最终都可以通过__proto__寻址到Object.prototype
- 凡是函数,最终都可以通过__proto__寻址到Function.prototype
- 函数的prototype是一个对象
from daily-interview-question.
这里在理解的时候可能会把Object.prototype.toString.call()与[12].toString()方法相混淆,如果把这两个toString方法当作是一个,那么后续的理解会造成困难。因为当我们期待Object.prototype.toString.call([12])返回一个12时,发现控制台打印的却是【object array】。
首先,得理解这两个方法为什么不是一个?[12]是Array的实例,那么他的toString方法就得从Array这个构造者的prototype中去寻找,发现确实有这个方法,那么直接调用即可,不会再向上去寻找toString。而Object.prototype.toString方法属于最顶层的方法,从位置上来看他俩压根就不是一个。
其次,他俩有什么样的关系呢?通过下面这个式子就可以理解了。
[12].proto===Array.prototype
Array.prototype.proto===Object.prototype
from daily-interview-question.
constructor可以被修改?
目测是可以被修改的
arr.constructor = '123'
arr. proto .constructor = '123'
可以console.log(arr.constructor)看下结果,然后再看一下__proto__中的constructor的结果
from daily-interview-question.
typeof 是什么原理呢?
哪位大神给讲讲
from daily-interview-question.
想仿写一下Object.prototype.toString,但是卡在了null 和 undefined的判断上,返回[object Window]... ...
from daily-interview-question.
具体来讲:每一个继承 Object 的对象都有 toString 方法,该方法返回[Object type];Array、function、Date等都继承于Object,但它们都改写了toString方法,所以阻断了对Object原型上toSting方法的调用。
验证:可以使用delete操作符删除原型实例上的toString方法,然后再调用toString,就可以调用到Object原型上的toString了。
题中用法是:直接调用原型方法,使用call改变this指向,以此来使对象直接调用原型方法。
from daily-interview-question.
但当除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
这里感觉不太清晰。事实上应该不是改变 toString 的上下文,而是改变调用的 toString 方法:const arr = [1, 2] arr.toString === Object.prototype.toString // false, 所以两者不同,实际上数组上重写了 toString 方法 const o = {o: 1} o.toString === Object.prototype.toString // true, 所以对象默认不需要如此调用。但如果将对象的方法改写就不一定了 o.toString = function changedToString() { return 'haha'; } o.toString() // 'haha' Object.prototype.toString.call(o) // '[object Object]'. 发现 Object.prototype.toString 也是可以被改写的...
call
方法的第一个参数会被当作this
,所以arr.toString()
与Object.prototype.toString.call(arr)
并没有改变this
,而是改变了调用的函数。
我觉得两者说的都没有问题,只是角度不同,对于Object的toString方法来说确实是修改了上下文,而对于Array来说,修改的是调用的toString方法
from daily-interview-question.
如果遇到精心设计的徦数组怎么判断呢?
var fakearray={length:0,__proto__:Array.prototype,[Symbol.toStringTag]:'Array'}
var fakearray=Object("fakestring")
fakearray.__proto__=Array.prototype
fakearray[Symbol.toStringTag]='Array'
用Array.isArray
判断结果是false
from daily-interview-question.
个人感觉题目有必要加上 typeof
from daily-interview-question.
想仿写一下Object.prototype.toString,但是卡在了null 和 undefined的判断上,返回[object Window]... ...
这两个都满足“不可变”性,也就是全局唯一,直接在你的判断函数中用 === 来判断好了,不等于这俩的再去做其他判断。
from daily-interview-question.
但当除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
这里感觉不太清晰。事实上应该不是改变 toString 的上下文,而是改变调用的 toString 方法:const arr = [1, 2] arr.toString === Object.prototype.toString // false, 所以两者不同,实际上数组上重写了 toString 方法 const o = {o: 1} o.toString === Object.prototype.toString // true, 所以对象默认不需要如此调用。但如果将对象的方法改写就不一定了 o.toString = function changedToString() { return 'haha'; } o.toString() // 'haha' Object.prototype.toString.call(o) // '[object Object]'. 发现 Object.prototype.toString 也是可以被改写的...
call
方法的第一个参数会被当作this
,所以arr.toString()
与Object.prototype.toString.call(arr)
并没有改变this
,而是改变了调用的函数。我觉得两者说的都没有问题,只是角度不同,对于Object的toString方法来说确实是修改了上下文,而对于Array来说,修改的是调用的toString方法
突然很好奇Object下原始toString都干了啥
from daily-interview-question.
var arr = [1, 2, 3]
Array.isArray(arr) // es5新增的 如果不存在可以使用Object.prototype.toString.call(arr)
// Array.isArray 要优于instanceof 因为Array.isArray可以检测出iframe
arr instanceof Array
arr.constructor === Array // 性能最好
Object.prototype.toString.call(arr) === '[objecr Array]'
from daily-interview-question.
Object.prototype.toString.call()
万金油,啥类型都能准确的判断,并且没有兼容性问题
instanceof
虽然 [] instanceof Array 返回true,但是 [] instanceof Object 也是true,说不出有啥缺点
Array.isArray()
ES6才有的新方法,有兼容性问题
各位大佬轻喷😸
from daily-interview-question.
from daily-interview-question.
Object.prototype.toString.call()
万金油,啥类型都能准确的判断,并且没有兼容性问题
instanceof
虽然 [] instanceof Array 返回true,但是 [] instanceof Object 也是true,说不出有啥缺点Array.isArray()
ES6才有的新方法,有兼容性问题
各位大佬轻喷😸
杠一下,Array.isArray() 在 ES5 就有了,兼容性很好
from daily-interview-question.
1. Object.prototype.toString.call()
每一个继承 Object 的对象都有
toString
方法,如果toString
方法没有重写的话,会返回[Object type]
,其中 type 为对象的类型。但当除了 Object 类型的对象外,其他类型直接使用toString
方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。const an = ['Hello','An']; an.toString(); // "Hello,An" Object.prototype.toString.call(an); // "[object Array]"这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined 。
Object.prototype.toString.call('An') // "[object String]" Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call(Symbol(1)) // "[object Symbol]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(function(){}) // "[object Function]" Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call()
常用于判断浏览器内置对象时。更多实现可见 谈谈 Object.prototype.toString
2. instanceof
instanceof
的内部机制是通过判断对象的原型链中是不是能找到类型的prototype
。使用
instanceof
判断一个对象是否为数组,instanceof
会判断这个对象的原型链上是否会找到对应的Array
的原型,找到返回true
,否则返回false
。[] instanceof Array; // true但
instanceof
只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true。[] instanceof Object; // true3. Array.isArray()
- 功能:用来判断对象是否为数组
- instanceof 与 isArray
当检测Array实例时,Array.isArray
优于instanceof
,因为Array.isArray
可以检测出iframes
var iframe = document.createElement('iframe'); document.body.appendChild(iframe); xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1,2,3); // [1,2,3] // Correctly checking for Array Array.isArray(arr); // true Object.prototype.toString.call(arr); // true // Considered harmful, because doesn't work though iframes arr instanceof Array; // falseArray.isArray()
与Object.prototype.toString.call()
Array.isArray()
是ES5新增的方法,当不存在Array.isArray()
,可以用Object.prototype.toString.call()
实现。if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
null和undefined不能直接使用toString:Cannot read properties of null/undefined
from daily-interview-question.
1. Object.prototype.toString.call()
每一个继承 Object 的对象都有
toString
方法,如果toString
方法没有重写的话,会返回[Object type]
,其中 type 为对象的类型。但当除了 Object 类型的对象外,其他类型直接使用toString
方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。const an = ['Hello','An']; an.toString(); // "Hello,An" Object.prototype.toString.call(an); // "[object Array]"这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined 。
Object.prototype.toString.call('An') // "[object String]" Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call(Symbol(1)) // "[object Symbol]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(function(){}) // "[object Function]" Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call()
常用于判断浏览器内置对象时。
更多实现可见 谈谈 Object.prototype.toString2. instanceof
instanceof
的内部机制是通过判断对象的原型链中是不是能找到类型的prototype
。
使用instanceof
判断一个对象是否为数组,instanceof
会判断这个对象的原型链上是否会找到对应的Array
的原型,找到返回true
,否则返回false
。[] instanceof Array; // true但
instanceof
只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true。[] instanceof Object; // true3. Array.isArray()
- 功能:用来判断对象是否为数组
- instanceof 与 isArray
当检测Array实例时,Array.isArray
优于instanceof
,因为Array.isArray
可以检测出iframes
var iframe = document.createElement('iframe'); document.body.appendChild(iframe); xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1,2,3); // [1,2,3] // Correctly checking for Array Array.isArray(arr); // true Object.prototype.toString.call(arr); // true // Considered harmful, because doesn't work though iframes arr instanceof Array; // falseArray.isArray()
与Object.prototype.toString.call()
Array.isArray()
是ES5新增的方法,当不存在Array.isArray()
,可以用Object.prototype.toString.call()
实现。if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }null和undefined不能直接使用toString:Cannot read properties of null/undefined
那是你没有定义变量....
from daily-interview-question.
Array.isArray()
是ES5新增的方法
Array.isArray()应该是ES6新增的方法哦
from daily-interview-question.
Related Issues (20)
- ``` javascript HOT 2
- 反转数字字符串 HOT 2
- es11
- 实现
- [...new Set(arr.toString().split(',').sort((a,b) => a-b ))].map(item => Number(item))
- let nums1 = [3,3,2] let nums2 = [1,2,3,3,2,2,4444] function res (nums1,nums2){ let a = [] for (const item of nums1) { for (const i in nums2) { if(item==nums2[i]){ a.push(nums2[i]) nums2.splice(i,1) break } } }; return a } console.log(res(nums1,nums2))
- splice插入
- 自己回答一波,若有错误请各位指出,互相学习!谢谢 ~
- 递归
- 第226题:TS 中逆变和协变如何理解
- objmap
- 通过协程来实现
- 这代码写的...
- 第 161 题:用最精炼的代码实现数组非零非负最小值 index HOT 2
- No description provided.
- > 就我的使用来说(Vue)key的作用是为了在数据变化时强制更新组件,以避免“原地复用”带来的副作用,官方文档也说明了**不带key性能更好**,见:[List Rendering - key](https://cn.vuejs.org/v2/guide/list.html#key)
- 解释原因
- an
- 同步/异步 > 微任务>宏任务
- Object.prototype,map
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from daily-interview-question.