01-JS资料

JS数据类型

var str = 'abc';
var num = 123;
var bool = true;
var und = undefined;
var n = null;
var arr=['x','y','z'];
var obj = {};
var fun = function() {};
console.log(typeof str);   //string
console.log(typeof num);   //number
console.log(typeof bool); //boolean
console.log(typeof und);   //undefined
console.log(typeof n);     //object
console.log(typeof arr);   //object
console.log(typeof obj);   //object
console.log(typeof fun);   //function 

对象

对象常用属性和方法

SON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串; JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

hasOwnProperty() 该方法可以判断对象的自有属性是否存在

assign() 该方法主要用于对象的合并,Object.assign(o1,o2)

defineProperties()直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

keys() 返回一个由一个给定对象的自身可枚举属性组成的数组,Object.keys(o);

values();返回一个给定对象自己的所有可枚举属性值的数组

entries();返回一个给定对象自身可枚举属性的键值对数组

属性的设置和获取

1、设置属性

var obj = {};

obj.name='aaaa';

obj['age'] = 20;

2、获取属性

obj.name;

obj['age'];

3、属性的删除

var o2= { name:'abc', age:18 };

delete o2.name;    

console.log(o2);

检测属性

检测属性 该方法可以判断对象的自有属性是否存在

in 运算符 检测属性是否存在于某个对象中,自有属性和继承属性都返回true

var obj={ name:'sonia', age:22 };

console.log('name' in obj);//自有属性

引用类型如何深拷贝

//引用类型深拷贝?结果证明是浅拷贝
//如果对象只有一级属性,Object.concat可以实现深拷贝
var arr1 = [1,2,3,[4,5]]
var arr2 = arr1.concat()
arr1.push(11)
arr1[3][0]=100; 
console.log(arr1);
console.log(arr2);


//Object.assign对于对象1级属性,可以是深拷贝,多级属性是浅拷贝
var o1= {id:10}
var o2 = Object.assign({},o1);
o1.id = 100
console.log(o1.id);
console.log(o2.id);

var o1= {id:10,test:'o1',children:{v:'o1'}}
var o2 = Object.assign({},o1);
o1.id = 100
o1.children.v='v2';
console.log(o1);
console.log(o2);

最简单的深拷贝方法是序列化

  var obj = {
    name: "fangfang",
    age: 18,
    children: { id: 1 },
  };
  var obj2 = JSON.parse(JSON.stringify(obj));
  obj.name = "alice";
  obj2.children.id = 99;
  console.log(obj);
  console.log(obj2);

但是序列化实现深拷贝有很多坑:

  1. 如果obj里存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间变成了字符串
  2. 如果obj里有RegExp、Error对象,则序列化后的结果只得到空对象
  3. 如果obj里有函数、undefined,则序列化的结果会把函数undefined丢失
  4. 如果obj里有NaN,Infinity,则序列化的结果会变成null
  5. JSON.stringify只能序列化对象的可枚举的自有属性。如果obj中的对象是由构造函数生成的,则使用JSON.parse()深拷贝后,会丢弃对象的constructor
  6. 如果对象中存在循环引用的情况,也无法进行正确的深拷贝

自定义深拷贝方法

  function deepCopy(newObj, obj) {
    var o = newObj;
    for (var key in obj) {
      if (typeof obj[key] === "object") {
        //判断obj[key]的类型,是数组还是对象,使用constructor严格判断对象是由谁构造出来的
        o[key] = obj[key].constructor === Array ? [] : {};
        deepCopy(o[key], obj[key]);
      } else {
        o[key] = obj[key];
      }
    }
    return o;
  }

预解析

JavaScript预解析,可以理解为把变量或者函数预先解析到使用的环境中

console.log(a);
var a = 10;
//结果输出undefined

预解析过程

第一步:预先解析var、function等,提升声明变量

第二步:预解析完毕后,逐行正常由上而下解析

f();//error
//函数表达式
var f = function () {};

fn();//OK
//函数声明
function fn() {}

//函数表达式和函数声明的最大区别是:预解析。函数声明有预解析功能
//也就是function声明的函数会在执行前提前解析

如果变量名和函数名相同了,谁的优先级高?

console.log(f);
function f(){console.log("456");
}
var f = 123;
//结果输出:[Function: f]


console.log(f);
var f = 123;
function f(){console.log("456");
}
//结果还是输出:[Function: f]

同名函数和变量,函数的优先级会更高,也就是函数取代变量。

方法内部也存在预解析:

  var b = 10;
  function f3() {
    console.log(b);
    var b = 100;
  }
  f3(); //undefined

  /**************解析过程***************/
  var b;
  function f3(){}
  b=10;
  f3();
  //f3方法内部预解析
  var b;
  console.log(b);//此时是undefined
  b=100;

作用域

作用域:它是指对某一变量和方法具有访问权限的代码空间,在JS中, 作用域是在函数中维护的。

表示变量 或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境

ES5的作用域只有两种:全局作用域和局部作用域(局部作用域又叫函数作用域)

var a = 1;
//if(true)的语句执行完成之后会自动销毁,从而将var a = 10,提升为全局变量
if (true) {
var a = 10;
}
console.log(a); //输出10

全局变量和局部变量同名的坑:

1、在全局变量和局部变量不同名时,其作用域是整个程序

2、在全局变量和局部变量同名时,全局变量的作用域不包含同名局部变量的作用域

var c = 30;
function f2(){
	var c;
	console.log(c);
} 
f2();//undefined

作用域链

执行函数的时候,先从函数内部寻找变量,如果找不到,会向创建函数的作用域内寻找变量

  var a = 1;
  function f1() {
    var a = 10;
    function f2() {
      var a = 20;
      console.log(a);//20
    }
    function f3() {
      console.log(a);//10
    }
    f2();
    f3();
  }
 f1();
 console.log(a);//1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值