数据类型
数据类型:7种
number
string
boolean
undefined
null
object
symbol
object
分为
array
object
function
判断一个值的类型
typeof
instanceof
Object.prototype.toString
> typeof 123
'number'
> typeof '123'
'string'
> typeof false
'boolean'
> typeof (function f(){})
'function'
> typeof undefined
'undefined'
> typeof null
'object'
> typeof NaN
'number'
> typeof global
'object'
> typeof {}
'object'
> typeof []
'object'
> undefined == null
true
> undefined === null
false
//undefined null在if语句中被转成false
> Number(null)
0
> 5+null
5
> null+5
5
> Number(undefined)
NaN
> 5+undefined
NaN
以下6个值布尔转成false
,其他为true
undefined null false 0 NaN ""或''
> Boolean(undefined)
false
> Boolean(null)
false
> Boolean(0)
false
> Boolean(NaN)
false
> Boolean(false)
false
> Boolean("")
false
> Boolean('')
false
//空数组 空对象是true
> Boolean([])
true
> Boolean({})
true
> Number([])
0
> Number('')
0
> Number(false)
0
> Number(null)
0
> Number(undefined)
NaN
> Number({})
NaN
字符串 不可改变,包括长度
对象
键名以字符串存储
{...}
解释为代码块
({...})
解释为对象
> eval('{foo:123}')
123
> eval('({foo:123})')
{ foo: 123 }
for ...in
遍历对象的属性
特点:1.遍历对象enumerable
为true
的属性,跳过不可遍历属性
2.还遍历继承的属性
判断某个对象是否具有某个属性
in
运算符
hasOwnProperty()
with
语句操作对象的多个属性
with
(对象){ 语句;
}
var obj = {
p1:1,
p2:2
};
with (obj){
p1=4;
p2=5;
};
log(obj); //{ p1: 4, p2: 5 }
函数声明
function
命令函数表达式
Function
构造函数
var print = function f(){
console.log(typeof x);
};
f(); //ReferenceError: f is not defined
//f只可以在函数体内部使用
//以及使用除错工具显示函数名
var add = new Function('x','y','return x + y');
console.log(add(1,2)); //3
length
属性:返回默认参数前的参数个数
function f(a,b,c){}
console.log(f.length); //3
function fun(a,b=3,c){}
console.log(fun.length); //1
toString()
返回源码 原生加上{[native code]}
const {log} = console;
function f(a,b,c){}
log(f.toString()); //function f(a,b,c){}
log(Number.toString()); //function Number() { [native code] }
log(Math.sqrt.toString()); //function sqrt() { [native code] }
变量提升
对于
var
命令来说,局部变量只在函数内部声明,其他区块都是全局变量
函数执行时所在的作用域
定义时所在的作用域
参数
如果函数参数传入对象地址,在函数内部修改对象属性,会影响到原始值
同名参数取最后出现的值
正常模式下,
arguments
对象可在运行时修改
var f = function(a,b){
arguments[0] = 2;
arguments[1] = 3;
log(a,b);
log(a+b);
}
f(1,2);
//2 3
//5
//严格模式下不影响实际参数
var f = function(a,b){
'use strict';
arguments[0] = 2;
arguments[1] = 3;
log(a,b);
log(a+b);
}
f(1,2);
// 1 2
// 3
将参数转成数组
var args = Array.prototype.slice.call(arguments);
callee
属性:返回参数对应的原函数
var f = function(){
console.log(arguments.callee);
}
f(); //[Function: f]
//arguments.callee调用函数自身,严格模式下禁止
闭包:能够读取其他函数内部变量的函数
用处:
1.读取函数内部的变量
2.让变量始终保存在内存中
3.封装对象的私有属性和私有方法
function createIncrementor(start){
return function(){
console.log(start++);
};
}
var inc = createIncrementor(5);
inc(); //5
inc(); //6
inc(); //7
function Person(name){
var _age;
function setAge(n){
_age = n;
}
function getAge(){
console.log(_age);
}
return {
name:name,
getAge:getAge,
setAge:setAge
};
}
var p1 = Person("张三");
p1.setAge(22);
p1.getAge() //22
eval()
eval()
没有自己的作用域,都在当前的作用域内执行严格模式下,eval内部声明的变量不会影响到外部作用域(仍然不安全)
规定:凡是使用别名执行
eval
,eval
内部一律是全局作用域
(function f(){
'use strict';
eval('var foo = 123');
console.log(foo); //ReferenceError: foo is not defined
})();
(function f(){
'use strict';
var foo = 1;
eval('foo = 2');
console.log(foo); //2
})();
//eval的别名调用,都是全局作用域
eval.call(null,'...');
window.eval('...');
(1,eval)('...');
(eval,eval)('...');8
数组是特殊的对象
可以给数组添加属性,但是长度不会变,因为
length
属性是将最大的数字键加1可以使用
for...in
遍历数组所有数字键,包括非数字键读取空位返回
undefined
delete
删除一个数组成员,会形成空位,不会影响length
属性数组的空位与某个位置是
undefined
不一样,forEach
,for...in
,以及Object.keys()
遍历数组会跳过空位,不跳过undefined
> var a = [];
undefined
> a['p'] = 'abc';
'abc'
> a
[ p: 'abc' ]
> a[2.1] = 'abc'
'abc'
> a
[ p: 'abc', '2.1': 'abc' ]
> a.length
0
//for...in遍历
var a = [1,2,3];
a.foo = true;
for (var key in a){
console.log(key);
}
// 0
// 1
// 2
// foo
//遍历数组
var a = [1,2,3];
for(var i=0; i<a.length; i++){
console.log(a[i]);
}
var i=0;
while(i<a.length){
console.log(a[i]);
i++;
}
//反向遍历
var i = a.length;
while(i--){
console.log(a[i]);
}
//forEach遍历
var colors = ['red', 'green', 'blue'];
colors.forEach(function(color){
console.log(color);
});
// red
// green
// blue
//delete数组成员
var a = [1,2,3];
delete a[1];
console.log(a[1]); //undefined
console.log(a); //[ 1, <1 empty item>, 3 ]
//Object.keys for...in for循环遍历不处理空值
console.log(Object.keys(a)); //[ '0', '2' ]
a.forEach(function(x,i){ //x是值,i时索引
console.log(i+':'+x);
});
// 0:1
// 2:3
for(var i in a){
console.log(i);
}
// 0
// 2
//不会跳过undefined
a[1]=undefined;
a.forEach(function(value,index){
console.log(index,':',value);
});
// 0 : 1
// 1 : undefined
// 2 : 3
类数组对象
所有键名都是正整数或零,并且有
length
属性
将类数组对象转成数组
var arr = Array.prototype.slice.call(arrayLike);
function logArgs(arrayLike){
Array.prototype.forEach.call(arrayLike, function(value,index){
console.log(index+':'+value);
});
}
var c = {
0:'a',
2:'c',
length:3
};
[].forEach.call(c,function(value,index){
console.log(index+':'+value);
});
// 0:a
// 2:c
logArgs(c);
// 0:a
// 2:c
[].forEach.call('abcde',function(value,index){
console.log(index+':'+value);
});
// 0:a
// 1:b
// 2:c
// 3:d
// 4:e
数据类型的转换
Number()
将任意数据类型的值转成数值转换规则:
1.调用对象自身的
valueOf()
方法,如果直接返回原始类型的值,则直接对其使用Number()
函数2.如果
valueOf()
返回对象,则调用对象自身的toString(),如果返回原始类型的值,则Number()
3.如果
toString()
返回对象报错
String()
Boolean()