JavaScript 学习笔记

/ 技术文章 / 0 条评论 / 1590浏览

JavaScript 学习笔记

基础语法

数据类型


if (!undefined) 
    console.log('undefined is false');
// undefined is false

if (!null) 
    console.log('null is false');
// null is false

undefined == null
// true

Number(null)
// 0

5 + null
// 5

Number(undefined)
// NaN

5 + undefined
// NaN

undefined 和 null用法区别

参数范围

Javascrip寻找变量策略

let globalVar = "This is a global variable"; 
  
function fun() { 
  let localVar = "This is a local variable"; 
  
  console.log(globalVar); 
  console.log(localVar); 
} 
  
fun(); 


// This is a global variable
// This is a local variable
let globalVar = "This is a global variable"; 
  
function fun() {  
  let localVar = "This is a local variable";  
} 
  
fun(); 
  
console.log(globalVar); 
console.log(localVar); 

// This is a global variable
// ReferenceError: localVar is not defined

let globalLet = "This is a global variable"; 
   
function fun() { 
   localLet = "This is a local variable"; 
} 
   
fun(); 
console.log(globalLet);
console.log(localLet); 

// This is a global variable 
// This is a local variable 

循环

//  for (i = 0; i < 10; i++) { //statement }
// while (x < 10) { //statement; x++;}
// for (variableName in Object) { //statement }


var languages = { first : "C", second : "Java", third : "Python", fourth : "PHP",  ifth : "JavaScript" }; 
 
for (itr in languages)  
{ 
    console.log('key', itr)
    console.log('value', languages[itr])
} 

宏任务微任务

单线程,先运行主线程,查询、运行并清空所有微任务,运行宏任务,查询、运行并清空所有微任务,运行宏任务重复上述过程

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

console.log('script start');

setTimeout(function() {
    console.log('setTimeout1');
    Promise.resolve().then(function() {
        console.log('promise1');
    })
}, 0);

Promise.resolve().then(function() {
    console.log('promise1');

    setTimeout(function() {
        console.log('setTimeout2');
    }, 0);
}).then(function() {
    console.log('promise3');
});

console.log('script end');

深拷贝 & 浅拷贝

基本数据类型

当一个变量向另一个变量复制基本类型的值,会创建这个值的副本,并且我们不能给基本数据类型的值添加属性。

var a = 1;
var b = a;
b = 2
b.name = 'hanna';
console.log(a); //1
console.log(b); //2
console.log(b.name); //undefined

引用类型

从一个变量向另一个变量复制引用类型的值,复制的其实是指针地址而已,因此两个变量最终都指向同一个对象。

var obj = {
   name:'Hello world',
   age: 22
}
var obj2 = obj;
obj2['c'] = 5;
console.log(obj); 
console.log(obj2); 

浅拷贝:只复制指向某个对象的指针,而不复制对象本身

var obj1 = {
    'name' : 'test',
    'age' :  '18',
    'language' : [1,[2,3],[4,5]],
};

var obj2 = obj1;


var obj3 = shallowCopy(obj1);
function shallowCopy(src) {
    var dst = {};
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop];
        }
    }
    return dst;
}

obj2.name = "test2";
obj3.age = "20";

obj2.language[1] = ["二","三"];
obj3.language[2] = ["四","五"];

console.log(obj1); 
console.log(obj2);
console.log(obj3);

深拷贝:复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变

function deepClone(source){
  const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  for(let keys in source){ // 遍历目标
    if(source.hasOwnProperty(keys)){
      if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{ // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    } 
  }
  return targetObj;
}

var obj = {
  name: 'test',
  sex: 'man',
  age: '18',
  func: function() {
      console.log('Do something')
  }
}
var obj2 = deepClone(obj);
obj2.age = '22'

console.log(obj)  
console.log(obj2) 

var obj = {
  name: 'test',
  sex: 'man',
  age: '18',
  func: function() {
      console.log('Do something')
  }
}
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.age = '22'

console.log(obj)  
console.log(obj2)  

undefined、function、symbol 会在转换过程中被忽略,只适合一些简单的情景(Number, String, Boolean, Array, Object),扁平对象,那些能够被 json 直接表示的数据结构。function对象,RegExp对象是无法通过这种方式深拷贝。
var obj = {
  name: 'test',
  sex: 'man',
  age: '18',
  func: function() {
      console.log('Do something')
  }
}
var { ...obj2 } = obj
obj.age = '22'
console.log(obj)  
console.log(obj2)