(一)、值类型和引用类型
为性能考虑,引用类型可能很大,存储 复制操作很费性能,所以栈中存地址,堆中存真是的数据
值类型(基础类型)
保存在栈中,占固定的空间
string number boolean symbol undefined
执行一个方法时,每个方法都会建立自己的内存栈,在这个方法执行结束后这个方法的内存栈也会随之销毁。
引用类型
保存在堆中,栈中存放这个变量的值的地址
对象 数组 null(null是特殊的引用类型,指针指向为空地址) 函数(函数是特殊的引用类型,但不用于存储数据,所以没有拷贝复制函数的说法)
堆内存中的对象不会随函数执行结束而销毁,因为这个对象还有可能被其他变量引用,只有当这个对象不被任何变量引用时,js回收机制才会把这个堆内存中的对象销毁
(二)、 typeof
能识别所有值类型 string number boolean symbol undefined
识别函数 function
typeof console.log // function
识别引用类型(不可再细分)把array null object都识别为 object
typeof null // object
(三)、变量计算 - 类型转换
字符串拼接
const a = 100 + 10; // 110
const b = 100 + `10`; // '10010' 遇到字符串全转为字符串
const c = true + `10`; // 'true10'
==
类型转换后的值
100 == '100' // true
0 == ''
0 == false
false == ''
null == undefined
// 除了== null之外 其他都用===
const obj = {a: 100}
if(obj.a == null){} // 相当于if(obj.a===null||obj.a===undefined){}
if语句和逻辑运算
truly变量 !!a === true的变量
falsely变量 !!a === false的变量
// 以下是falsely变量 除此之外都是truly变量
!!false === false
!!'' === false
!!undefined === false
!!null === false
!!NaN === false
!!0=== false
// truly 变量
const a = true
if(a){}
const b = 100
if(b){}
// falsely变量
const c = ''
if(c){}
const d = null
if(d){}
let e
if(e){}
逻辑判断
10&&0 // 0
''||'abc' // 'abc'
!window.abc // true
深拷贝
hasOwnProperty是js中唯一可以判断一个属性定义在对象本身而不是继承原型链的方法,主要用于判断某个对象中是否有某个属性,返回值为布尔值
// 深拷贝
const a = {name: 'mh', age: '21'}
function deepClone(obj){
if(obj == null || typeof obj != 'object'){
return obj // !!!!
}
let result;
if(obj instanceof Array){
result = []
}else{
result = {}
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key])
}
}
return result
}
const b = deepClone(a);
a.name = 'ww'
console.log('b,,,,,,',b);
遍历一个对象的所有自身属性
在看开源项目的过程中,经常会看到类似如下的源码。for...in循环对象的所有枚举属性,然后再使用hasOwnProperty()方法来忽略继承属性。
var buz = {
fog: 'stack'
};
for (var name in buz) {
if (buz.hasOwnProperty(name)) {
alert("this is fog (" + name + ") for sure. Value: " + buz[name]);
}
else {
alert(name); // toString or something else
}
}
注意 hasOwnProperty 作为属性名
JavaScript 并没有保护 hasOwnProperty 属性名,因此,可能存在于一个包含此属性名的对象,有必要使用一个可扩展的hasOwnProperty方法来获取正确的结果:
var foo = {
hasOwnProperty: function() {
return false;
},
bar: 'Here be dragons'
};
foo.hasOwnProperty('bar'); // 始终返回 false
// 如果担心这种情况,可以直接使用原型链上真正的 hasOwnProperty 方法
// 使用另一个对象的`hasOwnProperty` 并且call
({}).hasOwnProperty.call(foo, 'bar'); // true
// 也可以使用 Object 原型上的 hasOwnProperty 属性
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true