函数:
函数对任何语言来说都是一个核心概念,有了他我们可以实现任何功能。而且正如大家所认为的那样,它也是一个对象。因此他也是一个复杂数据类型(这部分的知识我们以后学习)。
函数的声明方式:
第一种声明方式:使用function
关键字声明一个:
//function关键字,加上空格,加函数名(函数的名字,实现什么功能就起什么样的名,函数名字的规则和变量起名的规则一样)和括号,加空格和花括号
function print() {
//接下来我们可以在函数里写任意多的代码
console.log(1)
}
我们声明了一个函数,他的功能是在控制台里打印1
(print -> 打印),然后这个函数并不会立马实现功能,需要我们手动调用:
print()//函数名后边加括号,让函数执行,此时我们在控制台里打印出了1
只有函数才可以加括号执行,其他数据类型都不可以!!!
console.log
和我们声明的print
做一个对比,发现console.log
的括号里传入了一个数字1
,控制台里打印的正是我们想要的1
,而我们在调用print
时的括号是空的,意思是我们自己声明的函数在调用的时候不能在括号里加入内容吗?其实不是的:
我们在调用
console.log
时括号里写的数据叫做:参数。
接下里我们写一个可以在括号里写参数的函数:
//声明了一个函数,函数名叫sayHi,say -> 讲
/*
这里我们在say的括号里写了一个name(当然它也可以是任意的一个英文),这个name学名叫做形参(具体的知识下边会详细分析),它的作用是允许我们在调用函数的时候在括号里写上其他数据。
*/
function say(name) {
console.log(name)
}
//第一次我们调用的时候先不在括号里加任何数据
say()//undefined
这里我们声明了一个名字叫做say
的函数,然后加括号调用,控制台里出现的竟然是undefined
,我们上次学基本数据类型的时候讲过undefined
表示的是未定义
,当我们声明一个变量,并没有为它赋值的时候,返回给我们的是undefined
:
var box
console.log(box)//undefined
而如果我们去打印一个从来没有声明过的变量时:
//some并没有用双引号或者单引号包裹起来,所以浏览器会认为他是一个变量,接下来我们去打印这个变量
console.log(some)//some is not defined,浏览器给我们报了一个错,错误的内容是:我们从来没有声明过一个叫做some的变量
[灯泡],心里独白:
/*
那么也就是说,我们在say这个函数里使用console.log方法(方法就是函数)去打印name时,浏览器把name当做了一个已经声明过了的变量?
*/
function say(name) {
console.log(name)
}
完全正确!,可是这个变量是在哪里声明的呢?我们并没有进行过var name
的操作呀:
函数的参数就是一个变量。即便我们没有手动的使用
var
去声明,浏览器也知道他是一个变量,因为这是js
的语法规则,我们可以这样写!
那么接下来我们尝试在调用say
这个函数的时候手动在括号里添加数据。
say(123)//打印出数字123
say('marko')//打印出字符串marko
say({a:1. b:2})//{a:1. b:2}
say([1, 2, 3, 4])//[1, 2, 3, 4]
十分精彩,我们在括号里写什么,控制台就能给我们打印什么!其实事情是这样的:
function say(name) {
name = 123//这一步是浏览器的活儿
console.log(name)
}
say(123)
function say(name) {
name = {a:1. b:2}//这一步是浏览器的活儿
console.log(name)
}
say({a:1. b:2})
当我们在调用say
这个函数时,在括号里写了数据,浏览器帮我们把数据赋值给了形参name
(函数名称say
后的括号里),而这个形参name
也由浏览器帮我们声明好了。所以我们传进去什么,就能再浏览器里打印什么!
而我们写在括号里的数据有另外的一个名字叫做:"实参"。也就是形参的值。
我们在来复习一下:
//data -> 数据
//我们声明了一个函数,这个函数的名字叫做doSomethind,函数名字后的括号里有一个单词:data,写在这里的单词叫做形参,有了形参我们就可以往函数里传递数据
function doSomething(data) {
console.log(data)
}
//接下来我们调用这个函数,在调用时的括号里写了123这个数据,写在调用时括号里的数据也有一个名字叫做:实参,浏览器会把实参赋值给形参。
doSomethind(123)
//也就是说浏览器进行了这样一步操作
function doSomething(data) {
data = 123//把实参123,赋值给形参data,也就是说这个叫做data的变量里存储着123这串数字
console.log(data)//123,因此我们可以在控制台里打印出123
}
其实不管形参还是实参,他们都叫做参数,只是写的位置不一样。
关于函数的知识先了解到这里,接下来玩点更刺激的:
数据类型的相互转换
搞清楚数据类型的相互转换,才能明白
JavaScript
奇怪的运算结果。数据在转化类型时,并不会改变原来变量里的值,而是返回一个新值
js
中的数据类型是可以互相转化的,需要用到js
的一些内置函数(API),请确保已经理解了什么参数。
- 简单数据类型:
String
字符串,Number
数字(普通的数字和NaN
),Null
空指针,undefined
未定义,Boolean
布尔值:true和false.
- 复杂数据类型:
Object
对象,Array
数组。
所有数据类型都可以转换成布尔值
Boolean
有两个值:true
真,false
假。原生
js
为我们提供了一个API(函数) ->Boolean()
,用于验证所有值的真假,把需要验证的数据传入这个函数,就可以返回一个true
和false
。
传入字符串:
//声明了一个变量,变量里存储了一个字符串
var a = 'hello world'
var b = '牛X'
var c = '123我爱你'
//接下来我们来验证一下变量a的真伪。
var a_a = Boolean(a)
console.log(a_a)//true
var b_b = Boolean(b)
console.log(a_b)//true
var c_c = Boolean(b)
console.log(a_c)//true
//当我们向Boolean()这个函数里传入一个字符串的时候会返回给我们true(真)
//而我们传入一个空字符串的时候则返回false(假)
var d = ''
var e = ""
Boolean(d)//false
Boolean(e)//false
上边我们每声明一个变量用了一次var
,每打印一次数据用了一次console.log()
,写起来非常麻烦,还设有更简单的写法:
//当我们声明很多变量的时候,可以写在一个var里,用逗号隔开
var a = 'hello world',
b = '天下第一',
c = '123我爱你'
//如果需要打印多个数据,每个数据间用逗号隔开即可
console.log(a, b, c)//'hello world' '天下第一' '123我爱你'
传入数字:
//zero -> 零 varify -> 验证
var num_one = 1,
num_zero = 0,
num_nan = NaN,
varify_one = Boolean(num_one),
varify_zero = Boolean(num_zero),
varify_nan = Boolean(num_nan)
console.log(varify_one, varify_zero)//true false false
//所有非0数字和NaN都是true,0为false
传入undefined:
var nothing = undefined
console.log(Boolean(a))//false
//由于javascript里声明变量并且没有为其赋值的时候会自动存储undefined,因此下边的写法同样成立
var nothing
console.log( Boolean(nothing) )//false
传入json形式的对象:
var obj = {},
obj1 = {a: 123}
console.log( Boolean(obj) )//true
console.log( Boolean(obj1) )//true
不论json
形式对的对象里有没有保存值,都是true
。
传入Array:
var arr = [],
arr1 = [1, 2, 3]
console.log( Boolean(arr) )//true
console.log( Boolean(arr1) )//true
不论是不是空数组,都是true
。
传入空对象Null:
var Null = null//null不能成为变量名,但是js是严格区分大小写的所以Null不是空对象
console.log( Boolean(Null) )//false
总结:
被转化为true | 被转化为false |
---|---|
非空字符串 | 空字符串 |
0和NaN之外的所有数字 | 0和NaN |
——(假装这一行被删除了) | undefined |
json形式的对象,Array | null |
所有数据类型都可以转换成字符串
JavaScript为我们提供了内置函数(API)
toString()
和String()
,通过.
的方式调用。
Number
数字转字符串:
//声明一个变量,里边存储的数据是数字10
var str_a = 10
console.log( str_a.toString() )//"10"数字会被转化成字符串
//数字转字符串默认是按10进制来转的,除此之外还有很多神奇的操作,比如转2进制,8进制,和16进制,只需在括号里传入一个数字就ok了,talk is cheap,show me your code
console.log( str_a.toString(2) )//1010,哎是不是很神奇?我们想要二进制的字符串就直接把2作为参数传递给toString,那我想要8进制,16进制的岂不是?
console.log( str_a.toString(8) )//12
console.log( str_a.toString(16) )//a
//完全没错,只需要把8和16作为参数传递进去就可以得到8进制和16进制的字符串。
Warning!数字转字符串的时候用String()
方法不能转成十进制以外的字符串。
null
,undefined
转字符串:
var null_a = null
console.log( null_a.toString() )//浏览器会报一个错误说明不能这样用。不要着急我们还有备用方案String()
console.log( String(null_a) )//"null"
var undefined_a = undefined
console.log( undefined_a.toString() )//报错
console.log( String(undefined_a) )//'undefined'
Object
json对象转字符串:
var obj_a = {a: 1, b: 2}
console.log( obj_a.toString() )//"[Object Object]" -> 这是一个字符串,这个字符串就张这个样子
console.log( String( obj_a ) )//"[Object Object]"
不管是使用String
方法(函数)或是使用toString
方法,得到的都是一个看不到里边内容的数组,并不是说json
对象不能转化为字符串,而是另有他法,具体的内容在后边学对象时会具体的讲。
Array
数组转字符串:
var arr_a = [1, 2, 3, 4]
console.log( arr_a.toString() )//1, 2, 3, 4
所有数据类型都可以转换成数字
JavaScript
为我们提供了三个内置函数(API)Number()
,parseInt()
和parseFloat()
用于将其他数据转为数字。其中parseInt
和parseFloat
是只针对字符串的。
String
字符串转数字:
var str_a = '',
str_b = '123',
str_c = '0123',
str_d = '000123'
console.log( Number(str_a) )//0
console.log( Number(str_b) )//123
console.log( Number(str_c) )//123
console.log( Number(str_d) )//123
在使用Number转化字符串为数字时,空字符串会被转化为0,如果字符串的引号里只有数字的话会转化成对应的数字,而且会忽略前边的0。
而如果字符串里引号里有数字有文字的话
var str_e = 'helloworld'
console.log( Number( str ) )//NaN
出现了!终于出现了!!!我们将一段文字,转化为数字的时候,得到的是NaN
(这不是一个数字)。这完全在情理之中。因为我不能用数字告诉别人我是大帅比。
刚才的str_e
里全是文字,现在我们在里边加一点数字来看一看:
var str_aa = '123我爱你',
str_cc = '我123爱你',
str_dd = '我爱你123'
console.log( Number(str_aa) )//NaN
console.log( Number(str_cc) )//NaN
console.log( Number(str_dd) )//NaN
不论我们把数字放在字符串的开头,中间还是结尾都无法解析。这好像不是很合理,如果以数字开头应该把开头的那些数字转换过来才对呀!没关系,我们还有两个API
没用:
parsentInt
和parseFloat
,talk is cheap,show me your code.
var str_aaa = '123helloworld'
console.log( parseInt(str_aaa) )//123
//以空格开头
var str_bbb = ' 123hello'
console.log( parseInt(str_bbb) )//123
var str_ddd = '-123hello'
console.log( parseInt(str_ddd) )//
var str_ccc'he123llo'
console.log( parseInt(str_ccc)//NaN
parseInt
方法在把字符串转化为数字时,如果字符串的第一位非空字符是数字或者正号、负号,就会一直往后找,找到出现小数点或者文字的时候就停止,然后把这些数字字符串转化为数字,<如果第一个非空字符不是数字或者正负号,直接返回NaN
。那如果是空字符串会怎样?
var str_eee = ""
console.log( parseInt(str_eee) )//NaN。
parseInt
是个大小姐脾气,并不会像Number
一样把空字符解析成0,其实很好理解,我们已经知道了一个字符串用parseInt
方法(函数)转成数字时,这个字符串要想不被转化为NaN
,则必须开头除了空字符串必须要有数字或者正负号。
除此之外他还不识别小数点.
:
var str_fff = '12.3'
console.log( parseInt(str_fff) )//12
parseInt
虽然有大小姐脾气但大小姐也必有出众的地方。Number
只能把字符串转化为10进制的数字,而parseInt
的能力不仅限于此:
parseInt()
可以接受第二个参数用于指定转化为多少进制的数字,不写默认是10,参数和参数之间用逗号隔开。
var str_ggg = '1234blue'
console.log( parseInt(str_ggg) )//1234
console.log( parseInt(str_ggg, 10) )//1234
console.log( parseInt(str_ggg, 2) )//1
console.log( parseInt(str_ggg, 8) )//668
console.log( parseInt(str_ggg, 16) )//74571
上边我们使用了parseInt
把字符串str_ggg
转变成了2进制、8进制、10进制和16进制的数字,这里可能有同学会奇怪为什么1234
转化成2进制后变成了1
!因为在2进制里只有0
和1
两个数字,也就是说大于1
的数字不会当做数字解析:
var str_one = '2'
console.log( parseInt(str_fff, 2) )//NaN
除了parseInt
之外,还有另外一个把字符串转为数字的方法(函数):parseFloat
:
parseInt
和parseFloat
是一对孪生姐妹,解析字符串的方法几乎一样,只是后者比前者多了解析小数点的能力,但是却没有转变2进制,8进制和16进制的能力。
var str_two = '12.3.5hello'
console.log( parseFloat(str_two) )//12.3
console.log( parseFloat(str_two) )//12.3
parseFloat()
在解析带小数点的数字时,遇到第二个小数点就会停止,这和我们生活中的计数方法一模一样,一个小数只能有1个小数点。
下边是其他数据类型转数字,除了字符串之外其他数据转数字用三种方法的哪一个都是一样的结果,我们以Number()
为例。
Undefined
和Null
转数字:
var str_three//赋值undefined和不赋值都一样
console.log( Number(str_three) )//NaN
var str_four = null
console.log( Number(str_four) )//NaN
数字转数字:
吃什么吐什么。
var num_a = 123
console.log( Number(num_a) )//123
好玩的来了!把十进制数字转成其他进制。
var num_b = 123
console.log( parseInt(str_fff, 2) )//1
console.log( parseInt(str_fff, 8) )//83
console.log( parseInt(str_fff, 16) )//291
咦?这里怎么不用parseFloat()
方法呢?别忘了parseFloat
最重要的功能是消化浮点数(小数)。
Null
&Undefined
转数字:
var nothing_one = null
var nothing_two = undefined
console.log( Number(nothing_one) )//0
console.log( Number(nothing_two) )//NaN -> NaN表示的意思是这不是一个数字,他属于数字
对象转数字:
我们来看看
Object
(Json
格式的对象),Array
是如何转化成数字的。
对象转数字的时候会js
会先对对象使用toString
转为字符串,再转为数字!
var arr_one = []
var arr_two = [1, 2, 3]
var arr_three = [3]
console.log( Number(arr_one) )//0
console.log( Number(arr_two) )//NaN
console.log( Number(arr_three) )//3
这里我们可能会感觉到奇怪,为什么同样是数组,arr_three
就可以转化为3而arr_two
就只能转化为NaM
呢?其实很好理解:
var arr_two = [1, 2, 3]
console.log( arr_two.toString() )//"[Object Object]" 上边我们已经说到过,它是一个字符串,这个字符串就长这个样子。
那么问题是不是就迎刃而解了呢?不是已数字和正负号开头的字符串都会被转化为NaN
。
而[3]
呢:
var arr_three = [3]
console.log( arr_three.toString() )//"3"
console.log( Number("3") )//3
接下来我们看看Json
格式的对象:
var obj_a = {}
var obj_b = {a: '123'}
console.log(Number(obj_a))//NaN
console.log(Number(obj_b))//NaN
原理和上边转化数组的时候一样!
对象转数字总结:
对象类型 | 不储存任何数据时 | 存数据时 |
---|---|---|
Object | NaN | NaN |
Array | 0 | NaN或数字 |