初步了解“==”,“===”,typeof(),instanceof

w3c规定:
在 ECMAScript 中,等号由双等号(==)表示,当且仅当两个运算数相等时,它返回 true。非等号由感叹号加等号(!=)表示,当且仅当两个运算数不相等时,它返回 true。为确定两个运算数是否相等,这两个运算符都会进行类型转换。
执行类型转换的规则如下:
如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
值 null 和 undefined 相等。
在检查相等性时,不能把 null 和 undefined 转换成其他值。
如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
重要提示:即使两个数都是 NaN,等号仍然返回 false,因为根据规则,NaN 不等于 NaN。

 console.log(null == undefined);//true
                console.log(null === undefined);//false
                console.log(0 == undefined);//false
                console.log(0 == null);//false
                console.log(0 == false);//true
                console.log(0 === false);//false
                console.log(1 == true);//true
                console.log(1 === true);//false
                console.log(false == NaN);//false
                console.log(false === NaN);//false
                console.log(false == undefined);//false
                console.log(false === undefined);//false
                console.log(false === null);//false
                
                console.log(typeof(undefined));//undefined
                console.log(typeof(null));//object
                var a = [];
                console.log(typeof(a));//object
                console.log(a instanceof Object);//true
                var b = function(){}
                console.log(typeof(b));//function
                console.log(b instanceof Object);//true
                var c = "hiksf";
                console.log(typeof(c));    //string
                console.log(c instanceof Object);//false
                var d = 3,e = "3",f="";
                console.log(typeof(d)); //number
                console.log(typeof(e));//string
                console.log(typeof(f));//string
                console.log(typeof(NaN));//number
                console.log(typeof(object));//undefined

                var aa = new Object();//在内存里开辟一片空间,然后将空间的首地址返回给aa。
                var bb = new Object();
                var cc = aa;
                console.log(aa == bb);//false
                console.log(typeof(aa));//object
                console.log(aa == cc);//true

JavaScript 标准文档中定义: [[Class]] 的值只可能是下面字符串中的一个: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String.
为了获取对象的 [[Class]],我们需要使用定义在 Object.prototype 上的方法 toString。
对象的类定义
JavaScript 标准文档只给出了一种获取 [[Class]] 值的方法,那就是使用 Object.prototype.toString。

function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}
is('String', 'test'); // true
is('String', new String('test')); // true

//上面例子中,Object.prototype.toString 方法被调用,this 被设置为了需要获取 [[Class]] 值的对象。
//****注:Object.prototype.toString 返回一种标准格式字符串,所以上例可以通过 slice 截取指定位置的字符串,**如下所示:**
Object.prototype.toString.call([])    // "[object Array]"
Object.prototype.toString.call({})    // "[object Object]"
Object.prototype.toString.call(2)    // "[object Number]"
//注:这种变化可以从 IE8 和 Firefox 4 中看出区别,如下所示:
// IE8
Object.prototype.toString.call(null)    // "[object Object]"
Object.prototype.toString.call(undefined)    // "[object Object]"
// Firefox 4
Object.prototype.toString.call(null)    // "[object Null]"
Object.prototype.toString.call(undefined)    // "[object Undefined]"
//测试为定义变量
typeof foo !== 'undefined'

如果想将null和对象区分开,则必须针对特殊值显式检测。如:my_value===null。对于宿主对象来说,typeof有可能并不返回‘object’,而返回字符串。但实际上客户端js中的大多数宿主对象都是‘object’类型。对于所有内置可执行对象进行typeof运算都将返回“function”。

// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
typeof Number(1) === 'number'; // 不要这样使用!

// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof返回的肯定是一个字符串
typeof String("abc") === 'string'; // 不要这样使用!

// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 不要这样使用!

// Undefined
typeof undefined === 'undefined';
typeof blabla === 'undefined'; // 一个未定义的变量,或者一个定义了却未赋初值的变量

// Objects
typeof {a:1} === 'object';
typeof [1, 2, 4] === 'object'; 
// 使用Array.isArray或者Object.prototype.toString.call方法
//可以分辨出一个数组和真实的对象
typeof new Date() === 'object';

typeof new Boolean(true) === 'object' // 令人困惑.不要这样使用
typeof new Number(1) === 'object' // 令人困惑.不要这样使用
typeof new String("abc") === 'object';  // 令人困惑.不要这样使用
// Functions
typeof function(){} === 'function';
typeof Math.sin === 'function';

关于instanceof
instanceof 左操作数是一个类,右操作数是标识对象的类。如果左侧的对象是右侧类的实例,则返回true.而js中对象的类是通过初始化它们的构造函数来定义的。即instanceof的右操作数应当是一个函数。所有的对象都是object的实例。如果左操作数不是对象,则返回false,如果右操作数不是函数,则抛出typeError。
instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性。其语法是object instanceof constructor
instanceof 操作符用来比较两个操作数的构造函数。只有在比较自定义的对象时才有意义。 如果用来比较内置类型,将会和 typeof 操作符 一样用处不大。
比较自定义对象

function Foo() {}
function Bar() {}
Bar.prototype = new Foo();

new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true

// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例

Bar.prototype = Foo;
new Bar() instanceof Foo; // false

instanceof 比较内置类型

new String('foo') instanceof String; // true
new String('foo') instanceof Object; // true

'foo' instanceof String; // false
'foo' instanceof Object; // false

有一点需要注意,instanceof 用来比较属于不同 JavaScript 上下文的对象(比如,浏览器中不同的文档结构)时将会出错, 因为它们的构造函数不会是同一个对象。

结论:instanceof 操作符应该仅仅用来比较来自同一个 JavaScript 上下文的自定义对象。 正如 typeof 操作符一样,任何其它的用法都应该是避免的。

function C(){} // defining a constructor
function D(){} // defining another constructor

var o = new C();
o instanceof C; // true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false, because D.prototype is nowhere in o's prototype chain
o instanceof Object; // true, because:
C.prototype instanceof Object // true

C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false, because C.prototype is nowhere in o's prototype chain anymore

D.prototype = new C(); // use inheritance
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

var myString = new String();
var myDate = new Date();

myString instanceof String; // returns true
myString instanceof Object; // returns true
myString instanceof Date;   // returns false

myDate instanceof Date;     // returns true
myDate instanceof Object;   // returns true
myDate instanceof String;   // returns false
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
var mycar = new Car("Honda", "Accord", 1998);
var a = mycar instanceof Car;    // returns true
var b = mycar instanceof Object; // returns true

猜你喜欢

转载自blog.csdn.net/qq_38233172/article/details/89041767
今日推荐