js 变量类型和计算

278 阅读3分钟

(一)、值类型和引用类型

为性能考虑,引用类型可能很大,存储 复制操作很费性能,所以栈中存地址,堆中存真是的数据

值类型(基础类型)

保存在栈中,占固定的空间
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