一、数据类型:
原始类型: | 引用类型 |
---|---|
null | object |
undefined | function |
number | |
string | |
boolean |
NAN也是数据类型,表示数据不应该存在。例如0/0的计算结果,就是NAN
typeof(xx)
的返回值即为基本数据类型,而这些数据类型显示都是字符串类型
typeof("1")//返回string
typeof "1"//也可以直接加空格再接参数,效果与加括号一样返回的也是string
原生JS里,只有手动赋值给一个变量null,才会产生null
未赋值的变量都是undefined
表达式一种数据,数据内容为表达式的计算结果
赋值表达式也是数据
console.log(a = 1 + 9 + 9)//结果为19
对象:
var obj = {
0:"number",
name:"daming",
'age':28,
sun:{
name:"xiaoming",
age:2
}
}
console.log(obj[0]) //number
js会把数字属性,自动转化为字符串。
四、显式类型转换
-- |
---|
Number(mix) |
parseInt(string,radix) |
parseFloat(string) |
String(mix) |
toString(radix) |
Boolean() |
1.Number(mix)
把字符串转换成数字。
Number(-123) // -123
Number(2.22) // 2.22
Number(null) // 0
Number(undefined) // NAN
Number("a") // NAN
Number("123abc") // NAN
2.parseInt(string,radix)
把参数转化成整数,并向下取整。
parseInt(1.1) // 1
parseInt(1.9) // 1
parseInt("-123.3") // -123
console.log(parseInt("0.1") === parseInt("-0.1")) // true
parseInt(string,radix)
有两个参数,默认第二个参数为10进制。该函数的意思是:radix进制的string,输出其在10进制下的结果
console.log(parseInt(10,16) ) // 16 把10转化为16进制,结果就是16
//意思是,十六进制的10,在10进制下,结果为16。
console.log(parseInt("b",16)) // 11
//十六进制的b,在10进制下,结果为11
//当参数为:不填 、字符串空、null、undefined、"abc" 、"123abc"之类的无法转化为数字的内容时时,
//返回NAN
3.parseFloat(string)
与 parseInt
类似。只是把参数转化为float类型。好处是不会像OC一样有浮动。
parseFloat("0.11a") // 0.11
parseFloat(123) // 123
//支持负数
4. String()
把参数转化成字符串。能把输入的任意内容转化成字符串。包括undefined
null
NAN
。
5.toString()
用法跟String()
有些区别。
toString()
参数在前,一般用于把对象转化成字符串:object.toString()
String(Object)
参数在中
两者区别在于
1.toString()
不能把null
,undefined
,NAN
作为参数。而String()
可以把上述3个直接转化成字符串。
2.不能直接111.toString()
。但是可以
var number = 111
number.toString()
toString()
还可以像parseInt()
进行进制转换。
var number1 = 10
var number2 = number1.toString(16)
console.log(number2)
// a
但是这里有一些细节要注意:
1:
object.toString(redix)
十进制的object,输出其在redix进制下的结果。
parseInt(object,radix)
:radix进制的object,输出其在10进制下的结果。
2:
toString()
是对象方法。所以前不能直接跟数字,例如1.toString()
就会报错。但是如上例一样,先把Number
类型赋值给变量number1
。就可以使用。同理boolean
类型也会报错。
6.Boolean()
有实际意义的参数,结果都是true
。包括函数,对象。undefined
null
NAN
返回fasle
五、隐式类型转换
-- | 隐式转换 |
---|---|
isNAN() | Number() |
++/-- +/-(正负符号如-1) | Number() |
+(加号) | 只要前后有字符串存在,就都拼接成字符串 |
- * / % | Number() |
&& !|| | Boolean() |
< > <= >= | 如果比较左右有数字,就会把不是数字的一端转化为数字。Number() |
== != | 如果比较左右有数字,就会把不是数字的一端转化为数字。Number() |
=== !== | 不发生类型转换 |
isNAN(object) 内部会先把object进行Number(object)转换,在拿结果与NAN进行比较。如果是NAN,则返回true。
console.log(isNAN(null)) // false
console.log(isNAN(undefined)) // true
console.log(isNAN("123")) // fasle
console.log(isNAN("abc")) // true
1 > 2 > 3
会先进行1 > 2 再把结果 > 3;
console.log(undefined == null) //ture
console.log(NAN == NAN) //fasle
console.log(typeof(a)) //console一个未定义的变量,只有这种情况不会报错,结果为字符串"undefined".
六:立即执行函数(匿名函数):
(function() {}) ()
(function() {} ())
作用是避免全局污染,强行改变作用域。
正常的函数调用的方法为:
function fun() {
}
fun()
但是如果这样写,就会报错。
function fun() {
}()
因为 function 可以是语句或者表达式
//语句
function fun(){
};
//表达式
var fun = function (){
};
为了避免解析上的歧义,JS规定,如果function出现在行首,一律解析成语句。
因此JS看到行首是function关键字以后,认为这一段都是函数定义,不应该以原括号结尾,所以就报错了。
七:this
-
在函数中使用this,它的指向完全取决于函数是如何被调用的
调用方式 示例 函数中的this指向 通过new调用 new method()
新对象 直接调用 method()
全局对象 通过对象调用 obj.method()
前面的对象 call method.call(ctx)
call的第一个参数 apply method.apply(ctx)
apply的第一个参数 call函数的理解
function func(e) {
console.log(this)
};
var obj = {
func2: function () {
}
}
func.call(obj)//{ func2: [Function: func2] }
//立即执行func()函数,但把func函数里的this指向obj.
- 伪数组转数组:
var obj = {
0: 'a',
1: 'b',
2: 'c',
length:3
}
console.log(Array.prototype.slice.call(obj))//[ 'a', 'b', 'c' ]
要理解这个转换,需要先理解slice()
的实际执行含义。
var arr = ['a', 'b', 'c']
console.log(arr.slice(1, 2))//[ 'b']
slice方法在上述语句中的的意思是:
对arr这个数组取其length为2的部分。从下标1开始读,每读到一个数据,就添加到数组中,最终返回这个数组。
理解了slice()方法,就能完全理解上述转换的原理了:
call()
方法,把slice()
里的this
指向obj
(因为obj是对象,没有slice()方法)。然后slice
会取obj
的length
,得到的结果是3
。然后从下标0
开始读,一直读到长度3
结束。把读到的结果,添加到数组中,并返回。
假如把上述obj改为:
var obj = {
0: 'a',
2: 'c',
3: 'c',
length:3
}
console.log(Array.prototype.slice.call(obj))//['a', empty, 'c']
八:构造函数
function Obj (name,age) {
this.name = name,
this.age = age,
this.sayHi = function() {
console.log(this.name+this.age)
}
}
var obj = new Obj('lili',18)
obj.sayHi();
因此可以看出,其实每个对象都是一个函数。每个函数也都是一个对象。
九:原型链
原型:
每个函数都会自动附带一个属性prototype
,这个属性的值是一个普通对象,称之为原型对象。
每个实例都拥有一个特殊的属性__proto__
,称之为隐式原型,它指向构造函数的原型
当访问实例成员时,先找自身,如果不存在,会自动从隐式原型中寻找
这样一来,我们可以把那些公共成员,放到函数的原型中,即可被所有实例共享
hasOwnProperty
判断一个属性是在自身而不是在原型上。
in
判断属性是不是在该对象自身或者原型上。
var obj = {a:1}
Object.prototype.b = 2;
console.log('a' in obj)//true
console.log('b' in obj)//true
原型链:
-
instanceof
关键字【常用】object instanceof constructor // 判断object的原型链中,是否存在constructor的原型
创建空原型的对象。
-
利用
Object.create()
Object.create(target); // 返回一个新对象,新对象以target作为隐式原型
-
利用
Object.setPrototypeOf()
Object.setPrototypeOf(obj, prototype); // 设置obj的隐式原型为prototype
十:继承
function inherit(Child, Parent){
//改变原型链即可实现继承。
Object.setPrototypeOf(Child.prototype, Parent.prototype);
}