简体   繁体   中英

Isn't the Array object different from the Object (thought typeof on both returns the same value)?

two of these tests fail. can anyone explain why and how to fix it?

var assert = require('assert').strict

Number.prototype.isNbr = true
Number.prototype.isStr = false
Number.prototype.isObj = false
Number.prototype.isArr = false

String.prototype.isNbr = false
String.prototype.isStr = true
String.prototype.isObj = false
String.prototype.isArr = false

Array.prototype.isNbr = false
Array.prototype.isStr = false
Array.prototype.isObj = false
Array.prototype.isArr = true

Object.prototype.isNbr = false
Object.prototype.isStr = false
Object.prototype.isObj = true
Object.prototype.isArr = false

describe('Number', () => {
    var x = 0;
    it('Is number', () => { assert.ok(x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('String', () => {
    var x = ''; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('Object', () => {
    var x = {}; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('Array', () => {
    var x = []; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(x.isObj) })
})

You can save to a file t.js and run like this:

$ mocha t.js

edit I

corrected line

var x = [];

which @MarkMeyer pointed out was wrong. in my original it was correct and correcting it doesn't change the results

as @Paulpro cleverly pointed out, my tests are bad. I was checking for .isObj where I should have been checking for .isArr

if I fix that everything works

To test for an array use Array.isArray(val) :

 var a = [1,2,3]; var b = {a:1}; console.log(Array.isArray(a)); console.log(Array.isArray(b)); 

The biggest reason your code was failing was because you were not calling .isArr . Look back at your code. You are calling .isObj twice in each.

 var assert = { ok(val) { if (!val) { console.error(`The value ${val} was not true.`); } else { console.info(' ✓'); } } } function describe(text, fn) { console.log(`Running test for: ${text}`); fn(); } function it(text, fn) { console.log(` -- ${text}`); fn(); } Number.prototype.isNbr = true Number.prototype.isStr = false Number.prototype.isObj = false Number.prototype.isArr = false String.prototype.isNbr = false String.prototype.isStr = true String.prototype.isObj = false String.prototype.isArr = false Array.prototype.isNbr = false Array.prototype.isStr = false Array.prototype.isObj = false Array.prototype.isArr = true Object.prototype.isNbr = false Object.prototype.isStr = false Object.prototype.isObj = true Object.prototype.isArr = false describe('Number', () => { var x = 0; it('Is number', () => { assert.ok(x.isNbr) }) it('Is string', () => { assert.ok(!x.isStr) }) it('Is object', () => { assert.ok(!x.isObj) }) it('Is array', () => { assert.ok(!x.isArr) }) }) describe('String', () => { var x = ''; it('Is number', () => { assert.ok(!x.isNbr) }) it('Is string', () => { assert.ok(x.isStr) }) it('Is object', () => { assert.ok(!x.isObj) }) it('Is array', () => { assert.ok(!x.isArr) }) }) describe('Object', () => { var x = {}; it('Is number', () => { assert.ok(!x.isNbr) }) it('Is string', () => { assert.ok(!x.isStr) }) it('Is object', () => { assert.ok(x.isObj) }) it('Is array', () => { assert.ok(!x.isArr) }) }) describe('Array', () => { var x = []; it('Is number', () => { assert.ok(!x.isNbr) }) it('Is string', () => { assert.ok(!x.isStr) }) it('Is object', () => { assert.ok(!x.isObj) }) it('Is array', () => { assert.ok(x.isArr) }) }) 

But this is not the best way to test these types. You are changing the prototype of built in objects. That is generally considered a bad practice.

You could do this:

 var assert = { ok(val) { if (!val) { console.error(`The value ${val} was not true.`); } else { console.info(' ✓'); } } } function describe(text, fn) { console.log(`Running test for: ${text}`); fn(); } function it(text, fn) { console.log(` -- ${text}`); fn(); } const isNbr = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Number' const isStr = val => Object.prototype.toString.apply(val).slice(8,-1) === 'String'; const isFun = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Function'; const isObj = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Object'; const isArr = val => Array.isArray(val); describe('Number', () => { var x = 0; it('Is number', () => { assert.ok(isNbr(x)) }) it('Is string', () => { assert.ok(!isStr(x)) }) it('Is object', () => { assert.ok(!isObj(x)) }) it('Is function', () => { assert.ok(!isFun(x)) }) it('Is array', () => { assert.ok(!isArr(x)) }) }) describe('Function', () => { var x = () => {}; it('Is number', () => { assert.ok(!isNbr(x)) }) it('Is string', () => { assert.ok(!isStr(x)) }) it('Is object', () => { assert.ok(!isObj(x)) }) it('Is function', () => { assert.ok(isFun(x)) }) it('Is array', () => { assert.ok(!isArr(x)) }) }) describe('String', () => { var x = ''; it('Is number', () => { assert.ok(!isNbr(x)) }) it('Is string', () => { assert.ok(isStr(x)) }) it('Is object', () => { assert.ok(!isObj(x)) }) it('Is function', () => { assert.ok(!isFun(x)) }) it('Is array', () => { assert.ok(!isArr(x)) }) }) describe('Object', () => { var x = {}; it('Is number', () => { assert.ok(!isNbr(x)) }) it('Is string', () => { assert.ok(!isStr(x)) }) it('Is object', () => { assert.ok(isObj(x)) }) it('Is function', () => { assert.ok(!isFun(x)) }) it('Is array', () => { assert.ok(!isArr(x)) }) }) describe('Array', () => { var x = []; it('Is number', () => { assert.ok(!isNbr(x)) }) it('Is string', () => { assert.ok(!isStr(x)) }) it('Is object', () => { assert.ok(!isObj(x)) }) it('Is function', () => { assert.ok(!isFun(x)) }) it('Is array', () => { assert.ok(isArr(x)) }) }) describe('Null', () => { var x = null; it('Is number', () => { assert.ok(!isNbr(x)) }) it('Is string', () => { assert.ok(!isStr(x)) }) it('Is object', () => { assert.ok(!isObj(x)) }) it('Is function', () => { assert.ok(!isFun(x)) }) it('Is array', () => { assert.ok(!isArr(x)) }) }) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM