02.函数的参数和数据类型的相互转换

函数:

函数对任何语言来说都是一个核心概念,有了他我们可以实现任何功能。而且正如大家所认为的那样,它也是一个对象。因此他也是一个复杂数据类型(这部分的知识我们以后学习)。

​ 函数的声明方式:

​ 第一种声明方式:使用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(),用于验证所有值的真假,把需要验证的数据传入这个函数,就可以返回一个truefalse

​ 传入字符串:

//声明了一个变量,变量里存储了一个字符串
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()方法不能转成十进制以外的字符串。

nullundefined转字符串:

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'

Objectjson对象转字符串:

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()用于将其他数据转为数字。其中parseIntparseFloat是只针对字符串的。

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没用:

parsentIntparseFloat,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进制里只有01两个数字,也就是说大于1的数字不会当做数字解析:

var str_one = '2'
console.log( parseInt(str_fff, 2) )//NaN

​ 除了parseInt之外,还有另外一个把字符串转为数字的方法(函数):parseFloat

parseIntparseFloat是一对孪生姐妹,解析字符串的方法几乎一样,只是后者比前者多了解析小数点的能力,但是却没有转变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()为例。

UndefinedNull转数字:

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或数字

你可能感兴趣的:(02.函数的参数和数据类型的相互转换)