谈谈我对JavaScript中类型和实例的深刻理解
这次主要讲javascript类型判断函数typeof和判断构造器原型instanceof的用法和注意事项。
类型
我们先来谈谈类型。首先要注意的是,typeof方法返回一个字符串来指示数据的类型。
Typeof是一元运算,放在操作数之前,操作数可以是任何类型。
它的返回值是描述操作数类型的字符串。通常,typeof只能返回以下结果:数字、布尔值、字符串、函数、对象和未定义。我们可以使用typeof来获取变量是否存在,比如if(typeof a!='undefined'){alert('ok')},而不是使用if(a),因为如果a不存在(未声明),则会发生错误。对于数组、null等特殊对象,typeof总是返回object,这是typeof的局限性。
语法解释
让我们先来看看每种数据类型对应的typeof的值:
数据类型undefined“undefined”null“object”布尔值“boolean”数值“number”字符串“symbol”(在ecmascript 6中新添加)“symbol”宿主对象(由JS环境提供,例如浏览器)依赖于实现的函数对象“function”和任何其他对象“object”然后看具体的例子:
//Numberstypeof 37===' number ';typeof 3.14===' number数学类型。LN2===' numbertypeof Infinity===' numbertypeof NaN===' number//虽然NaN是‘Not-A-Number’的缩写,但它的意思是‘Not Number’type of Number(1)===‘Number’;//不要这样用!//StringTypeof ' '===' string ';typeof ' bla '===' stringtype of(type of 1)===' string ';//typeof必须返回字符串type of string(' ABC ')==' string ';//不要这样用!//Booleanstypeof true===' boolean ';typeof false===' boolean布尔类型(真)==='布尔';//不要这样用!//Symbolstypeof Symbol()===' Symbol ';Symbol类型(' foo ')===' Symbol ';Symbol.iterator==='symbol '的类型;//Undefinedtypeof undefined===' undefined ';typeof blabla===' undefined//未定义的变量,或已定义但未赋值初始值的变量。//对象类型为{ a:1 }==' object//使用Array.isArray或Object.prototype.toString.call方法可以将[1,2,4]==='object '的数组类型与基本对象区分开;新日期()的类型===“对象”;//下面比较混乱,不要这样用!新布尔值的类型(true)===' object ';新数字(1)的类型====“对象”;新字符串的类型(' ABC ')===' object ';//function type of function(){ }===' function ';typeof Math.sin===' function我们会发现一个问题,就是typeof判断数据类型不准确。例如,数组、正则性、日期和对象类型的返回值都是object,这会导致一些错误。
因此,在判断类型类型的基础上,还需要使用Object.prototype.toString的方法来进一步判断数据类型。
让我们看看在相同数据类型的情况下,toString方法和typeof方法的返回值之间的区别:
Tostring类型的“foo”字符串新字符串(“foo”)字符串对象新数字(1.2)数字对象真布尔新布尔(true)。用布尔型新建Date () date对象新建Error () error对象新建Array (1,2,3) array对象/ABC/g regexp对象新建regexp(“喵”)RegExp对象,可以看出使用toString方法可以正确区分Array、Error、RegExp、Date等类型。
因此,我们一般使用这种方法来验证数据类型。
真题检测
然而,既然我们今天谈论的是typeof,这里有几个话题,看看我们是否真的掌握了typeof的用法。
第一个问题:
var y=1,x=y=的类型;x;第二个问题:
(函数f(f){返回类型f();})(函数(){ return 1;});第三个问题:
var foo={ bar : function(){ return this . baz;},baz : 1 };(function(){返回参数[0]的类型();})(foo . bar);第四个问题:
var foo={ bar : function(){ return this . baz;},baz : 1 } type of(f=foo . bar)();第五个问题:
var f=(函数f(){ return ' 1 ';},函数g(){ return 2;})();f型;问题6:
var x=1;if(function f(){ }){ x=type of f;} x;第七个问题:
(function(foo){ return type of foo . bar;})({ foo : { bar : 1 } });答案公布如下。这七个问题的答案是:
未定义','数字','未定义','未定义','数字',' 1未定义','未定义'
你有多少种方法做对了?是不是很混乱?虽然所有这些问题都有typeof,但是它们已经检查了javascript的许多基础。下面我们来详细解释一下。
第一个问题:
var y=1,x=y=的类型;x;//'undefined '表达式是从右向左的,x因为变量提升,类型不是null而是undefined,所以x=y x=y=“undefined”。
我在这篇文章中提到的变量推广,大家可以看一下。
第二个问题:
(函数f(f){返回类型f();//' number ' })(function(){ return 1;});传入的参数是f,这意味着function(){ return 1;}此功能。执行f()后得到结果1,因此typeof 1返回“number”。这个问题很简单,主要是区分f和f()。
第三个问题:
var foo={ bar : function(){ return this . baz;},baz : 1 };(function(){返回参数[0]的类型();//' undefined ' })(foo . bar);这个问题考察了这个方向。这总是指向函数执行时的上下文,而不是定义时的上下文(ES6的箭头函数不算)。当参数被执行时,它已经指向窗口对象。所以它是“未定义的”。不熟悉这个执行的同学可以看这篇文章:深刻理解这一点,对刚才提到的箭头函数感兴趣的可以看ES6的箭头函数。
第四个问题:
var foo={ bar : function(){ return this . baz;},baz : 1 } type of(f=foo . bar)();//未定义如果上面的问题做对了,那么这个问题应该不会错,这也是这个的指向问题。
第五个问题:
var f=(函数f(){ return ' 1 ';},函数g(){ return 2;})();f型;//‘number’很容易出错,因为在遇到这个问题之前,我从来没有遇到过javascript的分组选择器。什么是分组选择器?举个例子,你就会明白:
var a=(1,2,3);document . write(a);//3,最后一个为准,所以上面的题目会返回2,2的类型当然是“数字”。
问题6:
var x=1;if(function f(){ }){ x=type of f;} x;//'1undefined '这是javascript语言规范中的一个问题,所以在条件判断中加入函数声明。这个语句本身没有错,会返回true,但是javascript引擎在搜索时找不到这个函数。结果是“1未定义”。
第七个问题:
(function(foo){ return type of foo . bar;})({ foo : { bar : 1 } });其实这个问题是一个考察细节程度的话题。形式参数的foo指向整个{foo: {bar: 1}}。我相信会很清楚的。
好吧。以上话题都是很好的资源。
实例f
接下来,我们来谈谈instanceof方法。instanceof运算符可用于确定构造函数的原型属性是否存在于另一个要检测的对象的原型链中。
Instanceof用于判断一个变量是否是一个对象的实例,如var a=new Array();警报(数组的实例);将返回真,警报(对象的实例)也将返回真;这是因为数组是对象的子类。再比如:function test(){ };var a=新测试();警报(测试实例)返回。
说到instanceof,我们还需要插入一个问题,那就是函数的参数。我们可能都认为参数是一个Array,但是如果我们使用instaceof进行测试,我们会发现参数不是Array对象,尽管它们看起来非常相似。
如果对原型了解不多,可以看看,深入了解。
让我们看一下实例的实例:
//定义构造函数函数C(){}函数D(){ } var o=新C();//真,因为对象。(o)的getprototypeo==C . C的prototypeo实例;//false,因为原型不在o的原型链上例如d;对象的实例;//真,因为对象。原型。是(o)型转子返回对象的原型实例//真,同上c . prototype={ };var o2=新c();氧气实例为碳;//C的trueo实例;//假,c。原型指向了一个空对象,这个空对象不在o的原型链上。d .原型=新c();//继承var o3=新d();D的o3实例;//C的trueo3实例;//真但是这里我们需要注意一个问题:
函数f(){ return f;}文档。write(f的新f()实例);//false函数g(){ }文档。write(g的新g()实例);//真第一个为什么返回错误的呢?因为构造函数的原型被覆盖了,我们可以看看新f和新g的区别:
版权声明:谈谈我对JavaScript中类型和实例的深刻理解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。