描绘为Android/Java开发者的JavaScript精解(1)JS的数据类型。

React Native
的勃兴,似乎在渐渐印证那句名言:“凡是能因此JavaScript实现的,最终还见面用JavaScript实现!”为了不给时代抛弃,长期利用Java的我,集中5上时间读了JavaScript,结果就是:我太爱JavaScript了!凡在Java中感到难受的地方在此地都咬消云散了,天蓝蓝海蓝蓝,好死一切开绿油油草原!下面就记下下自己的学习过程,希望对广大准备学React
Native的Androiders有帮带。文章最后见面证明我实际的就学路径,觉得好就是假设碰赞哈!
流淌:本文讲述的JavaScript基于最新的ES6。

JavaScript
是一种弱类型或者说动态语言。这意味着不用提前声明变量的路,在程序运行过程中,类型会让机关确定。这也象征可以采取和一个变量保存不同种类的多少:

用作一个经年累月Javaer,我学JavaScript的方尽管是比着法,努力分辨清楚Java与JavaScript的同与异,在比较受到强化了解认识,最后及学会JavaScript的目的。

var foo = 42; // foo is a Number now
var foo = “bar”; // foo is a String now
var foo = true; // foo is a Boolean now

多多程序语言都有谈得来之口号,Java的口号是:“write once,run
everywhere!”同样,JavaScript也发生投机的口号,那就是“everything is
object!”我的求学也是由这句话开始之,为这个我索要将明白以下问题:

风行的JavaScript标准定义了 7 种植多少列,它们分别是:

  1. 于JavaScript中,对象(object)到底是什么?
  2. 以JavaScript中,基本数据列是目标为?
  3. 每当JavaScript中,数组是目标也?
  4. 于JavaScript中,函数是目标呢?
  5. 当JavaScript中,对象能够继承吗?
  6. 每当JavaScript中,创建对象的主意来略?
  7. 于JavaScript中,如何使用函数这种特别的目标?
    搞懂上面的题材后,我而追了之类问题:
  8. 于JavaScript中,闭包是呀?
  9. 当JavaScript中,变量有作用域吗?
  10. 以JavaScript中,有什么样奇技淫巧是Java所未曾底?
6种原始类型:
  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol(在ES6着初定义,本节暂不上课)
  • 对象(Object)类型

辟谣这些题目后,再失去读React
Native,就未会见发生语言达到的困难了,真的好开心!终于能与React
Native愉快地嬉戏了!

原始值

在JavaScript中除去 Object
以外的有着品类且是不可变的(值我无法为改),我们遂这些项目的价为“原始值”。

布尔列:Boolean
布尔代表一个逻辑实体,意呢真正、假,可以发少数个价:true和false。

Null类型:null
Null 类型只发一个价:null,表示空值,表示不曾让展现。

Undefined类型:Undefined
一个从未为赋值的变量会有个默认值undefined。

数字型:Number
每当JavaScript里,数字型会代表的限是(-(2底63次于方-1) ~
(2底63次方-1)。除了现实的数值,在JavaScript中还有有牵动符号的价:+Infinity,-Infinity和NaN(非数值,Not-a-Number),分别代表正无根本、负无穷和非数值。例如:
19 / +0; // Infinity
19 / -0; // -Infinity

字符串类型:String
JavaScript的字符串类型用于表示文本数据。在字符串中的每个元素占据了字符串的职务。第一独要素的目录为0,下一个是索引1,依此类推。字符串的长度是它的因素的数。
以JavaScript中的字符串需要采用单引号’‘或对引号”“括起来,表示该值是一个字符串。
JavaScript
字符串是不行变更的。这意味字符串一旦被创造,就非能够让改动。但是,可以依据对原始字符串的操作来创造新的字符串。例如:

  • 取得一个字符串的子串可通过甄选各自字母或应用String.substr()。
  • 有限个字符串的总是使用连接操作符 (+) 或者String.concat()。
  • 标记类型:Symbol
    符号(Symbols)是ES6初定义之。符号类型是唯一的又是不足修改的。Symbol不当作pre-course的上要。

同一、在JavaScript中,对象(object)到底是什么?

一言以蔽之,在JavaScript中,对象就是是一个Map,里面独自发键值对,除此之外,啥也尚无!

对象:Object

javascript
中的对象(物体),和另外编程语言中的靶子同,可以遵循现实生活中之对象(物体)来喻她。
javascript
中目标(物体)的概念好随着现实生活中实实在在的体来了解。
于javascript中,一个对象可以是一个单身的装有属性与项目的实业。我们用其与一个盏做下类比。一个盏是一个目标(物体),拥有属性。杯子有颜色,图案,重量,由什么材质构成等等。同样,javascript对象为有性来定义其的表征。
目标足以经过new操作符后与要创造的靶子类型的称号来创造。而创办Object类型的示范并为那个补偿加属性和(或)方法,就足以创建于定义对象,如下所示:

var o = new Object();

俺们为足以透过下的道一直开立一个目标:

var person = {
name: ‘Bob’,
age: 20,
gender: ‘male’
};

上述目标就定义了一个叫吧’Bob‘,20春秋,的男生。

1、创建对象

来,让咱们创建一个对象:
var person = new Object();
熟悉的new出现了,很亲切。var 是只新物,来探望它是啊。

在Java中我们要声明一个变量,必须指明它的种类,如下所示:
Person person;
Dog dog;
Cat cat;

故此要指明变量的门类,是以Java是一个静态类型的语言,如果不声明,编译器将无法知晓我们声明的变量。与Java正好相反,JavaScript是一个动态类型的语言,声明变量的时刻不需指明变量的路,只需要一个var
关键字就可了,变量可以是随机档次,只有在你使用变量的上,JavaScript才会动态确认变量的品类。

typeof操作符

由于JavaScript是高枕无忧型的,因此用来同等种手段来检测给定变量的数据类型——typeof就是背负提供即时地方信息之操作符。对一个价使用typeof操作符可能回下列某个字符串:

  • ‘undefined’ —— 未定义
  • ‘boolean’ —— 布尔值
  • ‘string’ —— 字符串
  • ‘number’ —— 数字值
  • ‘object’ —— 对象或null
  • function —— 函数 下面展示一下采用typeof的以身作则:

var message = ‘some string’;
alert(typeof message); // “string”
alert(typeof(message)); // “string”
alert(typeof 95); // number

在实际上编程的过程被,可以就此typeof判断任何一个变量的数据类型。

2、添加属性

每当对象涵盖的键值对被,键被誉为对象的特性,值为喻为相应的属性值。所有的键都是字符串,而值可以是擅自的种。

给我们呢地方的目标上加点儿只属性:
person[‘name’] = ‘milter’;
person[‘age’] = 31;

此间还要起一个初物,在JavaScript中,单引号和双引号都可据此来创造字符串,二者是同样的。
下面我们尽管得看这些属于性值了:
var name = person[‘name’] ; // milter
var age = person[‘age’] ; // 31

3、简便方法

以上创建对象、添加属性、访问属性的计大愚蠢:

  • 加加属性和访问属性的语法呆板(需数输入[] 和’ ‘)
  • 如出一辙浅只能添加一个性

为了解决创建对象和添加属性的笨,JavaScript提供了创建对象的大括哀号({
})语法:

var person ={‘name’ : ‘milter’, ‘age’: 31 };

这样,可当创建对象的还要也夫与多个特性。

题材尚没有缓解,上面赋予属性时还欲写单引号,访问属性时还要写中括号和单引号。
呢是,JavaScript进一步规定:如果代表属性之字符串符合JavaScript的标识符命名规范,那么尽管好看去字符串外面的单引号,同时可行使object.prop语法访问属性。

JavaScript的标识符命名规范如下:

  1. 区别轻重缓急写,Myname与myname是鲜单不同之标识符。
  2. 标识符首字符可以是以下划线(_)、美元入($)或者字母开始,不克是数字。
  3. 标识符中其它字符可以是下划线(_)、美元入($)、字母或数字组成的。
  4. 重点字和保留字不克作为标识符。

众所周知,我们的name和age属性符合这标准,所以现在我们得以如此写了:
var person ={ name : ‘milter’, age: 31 };
var name = person.name ; // milter
var age = person.age ; // 31

再可怜的是,我们可于目标创建出来后,继续为它们丰富或去属性,如下:

person.sex = ‘man’ ;
如上也person对象上加了让sex的性质,其值为字符串’man’。

delete person.sex ;
如上删除了目标person中的sex属性。

你或特别怀念问问,对象被之方式难道也是性,也是键值对?答案是YES,后面摆到函数时会仔细说,暂且按下。

其次、 在JavaScript中,基本数据列是目标啊?

JavaScript中的主导数据列有6种:

  • String
  • Number
  • Boolean
  • Symbol
  • undefined
  • null

同Java相比,String 和Boolean含义基本没换。
落一个String值的措施以达标文中已经干,就是用单引号或者双引号括起一段字符即可。

Boolean只发少个值 true和false,不用自己创立,直接以来所以就得。

Number只能是夹精度浮点数,就是Java中之double。

Symbol是单新品类,在ES6蒙受援引。它的每个值都是惟一的,获取一个Symbol值的语法是
: Symbol(String)。
例如:
var symb1 = Symbol(‘one’);
var symb2 = Symbol(‘one’);

var symb3 = Symbol();
var symb4 = Symbol();

鉴于达到可见,String是可选的,不管生没有发生String,都能够因此这种语法获取一个Symbol值。String只是吗这个Symbol值增加了一个叙而已。Symbol的价都是惟一的,是指你切莫可知少赖沾同样的Symbol值(正如人不可能有限不良踏入相同修河,请叫我哲学家)。比如Number这种多少列,我好数获取1之价值,并把它们赋予给不同的变量:

var number1 = 1 ;
var number2 = 1 ;

number1和number2是相当的,String和Boolean也可以这样做。
然Symbol不是这样的!。上文中, symb1 != symb2,symb3 != symb4

起Java转过来的总人口,感到这种写法很别扭,总想在Symbol前增长一个new,千万不要这么,JavaScript是匪同意的。
恳请牢记,这里没开创任何对象,仅仅是创建了一个旷世之值。

Symbol很像Java中之UUID,Symbol()就一定给UUID.randomUUID()。

undefined和null这简单种多少类且仅仅发一个值,就是它的门类名。undefined用于表示变量未初始化,null用于表示对象为空。

返回本节的题材,基本数据类是目标呢?答案是 NO!
说她不是目标,原因产生星星点点点:

  1. 其是不可变的。上文中,创建有person对象后,还能够延续为它多与去属性,也得以转移旧属性的值。基本数据列只发生一个价值,它们从不啊性质可改或添删。而且要得到一个值,这个价值就是无容许改变。这或多或少,很像Java中String的不可变性。
  2. 她的比较和传递都是基于值的,对象的于和传递是因引用的。例如:
    var a = ‘one’ ;
    var b = ‘one’;
    var c = {one:1};
    var d = {one:1};
    var e = c ;
    方,a和b是当的,因为少单变量有着同样的值,c和d是休对等的,因为少独变量指于星星个不等之目标,但是e和c是当的,因为她都对准同一个目标。如果你这么做:
    e.one = 2 ;
    这就是说您会意识 c.one也会见变成2。

凑巧如Java中发出基本数据列的包装类(Integer和int
,Double和double等)并得以活动装拆箱一样,JavaScript也发相近之编制,而且实现的尤为彻底。

回头看六种基本数据类,发现前方四栽之首字母是大写的,那是坐JavaScript为它创建了包装对象,最后两独undefined和null首字母是稍稍写的,因为JavaScript没有呢它提供包装对象。以String为例,代码
var str = new String(‘one’);
会面就此字符串’one’创建一个字符串对象str,String对象有无数操作字符串的艺术而供应你调用。Number和Boolean也与的接近,你可
var num = new Number(3.1415);
var bool = new Boolean(true) ;
足采取 typeof语法来证明其是匪是目标。
typeof bool //object
typeof num //object
typeof str //object

唯独Symbol是个不同,你切莫克采取new语法创建一个Symbol值的包裹对象,JavaScript是异常勿鼓励用Symbol值包装成靶子的,在实际应用着,这样的要求不行酷少!假设你特别怀念拿一个Symbol值包装成靶子,只能这样
var sym = Symbol();
var wrapSymbol = new Object(sym);

一如既往,与Java有自动装拆箱一样,JavaScript也发生相近的体制,且再次灵敏。简单讲,当您管中心数据作为对象来运时,它就会见自行成为一个靶(undefined和null除他,原因前面已经证明)。
举例如下:
var hello =’hello’;
var str = hello.slice(1); //str 的值是’ello’

这点比Java要方便!

其原理是:JavaScript
发现我们针对基本数据列hello进行了slice方法调用,它见面因此hello的值创造一个即之包裹对象,即new
String(hello),然后在这包裹对象及调用slice(1),返回基本数据类字符串’ello’。随后,这个临时之包裹对象就见面让灭绝。

老三、在JavaScript中,数组是目标也?

核心数据列不是目标,JavaScript的口号已经协调打脸。现在后续来拘禁数组。先说答案:数组是目标!
JavaScript中,可以这样定义一个数组。
var arr = [ ‘one’, ‘two’, ‘three’ ];

乍一扣,似乎没有键值对,但是,JavaScript会将方的代码转化成为下面这样:
var arr = { ‘0’:’one’, ‘1’:’two’, ‘2’:’three’ } ;
经我们解,数组属于对象确定无疑!!
妇孺皆知以第一栽写法更加从简直观,你可认为它们是概念数组的语法糖。
今日,我们来聘数组中的元素。按照前面学习之目标知识,似乎应当这么看数组元素:
arr.0 , arr.1, arr.2

其实情况是,这是无容许的!为什么吧?

前面我们提过,只有属性字符串符合JavaScript的标识符命名规范时,才会就此圆点语法(object.prop)访问对象的性能。而于点的数组中,属性字符串是’0′,’1′,’2′,它们还是以数字开的字符串,不适合标识符命名规范,所以我们无能够用圆点语法访问数组中的元素。

这就是说怎么看?用为重的访问对象属性的艺术,如下:

arr[‘0’], arr[‘1’], arr[‘2’]

由于数组使用的效率实在太胜,让用户每次访数组元素都要写单引号,太烦琐,JavaScript对数组对象做了特别的优化,可以为您看看去单引号,直接这样描写:
arr[0], arr[1], arr[2]

优化的法则非常简单,在幕后,JavaScript会自行将中括号丁之东西两侧长单引号。
不过这么就会见带一个特别微妙的问题,假如我们这样写:
arr[01]
那,JavaScript就会见把它转化成这么:
arr[’01’]
深显然,对象 arr
中无’01’这个特性,因为字符串’1’和’01’是勿齐的,为避这样的荒唐,JavaScript就不准了在访问数组时输入开头为0的数字,它会报生
Invalid Number错误,提示您改改。

此外,JavaScript数组对象有一个length属性,非常迷惑人,请看下面的代码:
var arr = [‘one’, ,’three’];
以斯数组中,只有我们只初始化了简单单元素,第二只因素我们留空了,在java中,这是无同意的,也就是说,你莫可知以java中这样初始化数组:
int [] arr = {1,,2}//这样写会报错的。JavaScript会将地方的代码转化成这样:
var arr = {‘0′:’one’,’1′:undefined,’2′:’three’};
假若测试 arr[1] == undefined,你见面博得结果true。
arr.length的值仍然是3。严格来说,arr.length的值等于最后一个元素的index再添加1。

季、在JavaScript中,函数是目标啊?

以JavaScript中,函数首先具有Java中艺术的性,就是收输入,进行操作,根据需要有输出。
相同,先说答案:函数是目标!

1、函数的定义

JavaScript中,定义一个函数有点儿种植艺术:声明的章程同表达式的方。

  • 宣示的法:

     return a+b ;
};```
- 表达式的方式:
```var foo2 = function (a,b) {
     return a + b;
};```
上面第一种方式定义了一个名为foo1的函数,第二种方式定义了一个名为foo2的函数,二者有什么区别?

最主要的区别是**可用时机**不一样。假设foo1和foo2存在于同一个js文件中,js引擎加载并执行该js文件的具体过程是:
首先扫描整个文件,找出并加载foo1;
然后逐条语句解释执行,文件中任何地方出现的foo1调用(不管是在foo1定义之前还是之后)都可以被正确处理,因为js引擎已经提前加载了该函数。
当执行到定义foo2函数的行时,才会加载这个函数,在之后的语句中才能调用foo2函数,如果在定义foo2函数的行之前使用foo2,程序将会报错。

简单讲,声明方式定义的函数会在程序执行之前加载,程序文件的任何地方都可以使用声明方式定义的函数。表达式的方式定义的函数只有在执行到定义函数所在的行时,才会加载,才能在之后的语句中使用该函数。

问题来了,看看下面这种定义函数的方式:

var foo2 = function foo3(a,b) {
return a + b;
};

咦!这是什么鬼?它属于哪种函数定义方式?这个函数的名字到底是foo2呢还是foo3呢?为什么要搞这么诡异的函数定义方式?

简言之,它属于表达式的方式定义的函数,函数的名字是foo2,foo3存在的**唯一目的**就是为了在该函数内部使用该函数(实现递归),在程序的其他地方foo3都是没有意义的,在这一点上,可以认为foo3的作用域在该函数的内部。

现在可以来解释对象的方法问题了。对象的方法也是一个属性,此时,属性的名字就是函数的名字,属性的值就是一个函数。举例说明如下:

var obj = {
add: function(a,b){
return a+b;
}
};

上面的代码中,对象obj有一个属性add,它的值是一个函数,函数的名字就是属性的名字add,所以,你可以这样使用obj:
var  result   =   obj.add(4,9);              //    result == 13

上述定义函数的方式属于表达式方式,也就是说,只有对象被创建后,add函数才会被加载。对象也可以使用声明方式定义的函数作为属性值,如下所示:

var obj = { };
obj.add1 = add ;

function add(a,b){
return a+b;
};

上面的代码中,我们把以声明方式定义的函数add赋值给obj的一个名为add1的属性,此时你就可以这样使用了:
var   result = obj.add1(4,9);     //result == 13

那么问题来了,此时的add1和add是什么关系?仅仅是一个函数的两个名字吗?答案是: **NO!**这涉及到函数的另一个概念scope,后面会讲,暂且按下。

理解了对象的方法也是键值对后,我们可以更彻底地理解文章开头的那句话:
**在JavaScript中,对象就是一个Map,里面只有键值对,除此之外,啥也没有!**

搞清楚了函数的定义方式,理解了对象的方法也是键值对,我们来看本节主题:**函数也是对象!**

我们以上面定义的函数foo1(声明方式定义)和foo2(表达式方式定义)为例来说明。
函数是对象,最明显的证据就是我们可以为它增加、删除、修改属性。如下:
- 增加属性:
foo1.prop1 = 'first prop';
foo1.prop2 = 'second prop';
foo2.prop1 = 'first prop';
foo2.prop2 = 'second prop';
- 修改属性:
foo1.prop1 = 'changed prop';
foo2.prop1 = 'changed prop';
- 删除属性:
delete foo1.prop1;
delete foo2.prop1;

事实上,我们可以把函数当作一个**特殊的对象**,这个对象是可以被调用的(a object which can be called!)。除了这点特殊性,函数就与一般对象没有什么明显的区别了。

**小结:**现在,我们已经解决文章开头提出的10个问题的前4个,这让我们非常彻底地理解了JavaScript中的那句口号:“Everything is object”。我们获得了如下知识:
- 对象就是键值对的集合,除此之外,它啥也没有。
- JavaScript有6种基本数据类型,它们**不是对象!**
- 数组是对象,虽然乍一看并不像。
- 函数也是对象,只是有点特殊,是一种可以被调用的对象。

动手写这个系列的初衷,是想给广大的Android开发者学习React Native提供一个有针对性、精炼的JavaScript快速入门教程,默认大家对Java都比较熟悉。所以,对JavaScript和Java比较相似的地方都没有涉及,比如 for 、while、if语句等,而把重点放在JavaScript明显区别于Java的内容上,同时尽量从Java和JavaScript比较的角度来写,目的是方便大家的理解。

另外,由于是为React Native学习做准备,所以对JavaScript中与网页处理相关的内容也尽量避开了。

我很想知道这样的写作方式能不能实现我的初衷,如果你觉得这种方式还不错,请给我点个赞,我会根据大家的反馈决定要不要坚持写下去。

相关文章