JavaScript知识点02

1 Object添加属性:defineProperty

格式:Object.defineProperty(obj,prop,desc)
obj:需要定义属性的对象
prop:需要配置的属性名称
desc:属性描述对象

其中:desc分为两种,不可同时使用:

  1. 权限描述
// 权限描述对象,(不写默认值为false)
{
  value:xxx,
  writable:false, // 不可重新赋值,但是如果可配置,可以使用defineProperty重新赋值
  enumerable:false, // 不可枚举
  configurable:false // 不可删除或重新defineProperty配置,但是当writable为true时,可以再次定义来改变value值
}

// 直接索引赋值
let o = {}
o.a =1 
// 相当于
Object.defineProperty(o,'a',{
  value:1,
  writable:true
  enumerable:true
  configurable:true
})
  1. 存取器
{
  get: function(){},
  set: function(){}
}

// 示例
var number = 18
var a ={name:"pp",sex:"boy"}
Object.defineProperty(a,'age',{
	get(){
		return number;
	}
	set(value){
		number = value
	}
})
console.log(a.age) // 18
number = 19
console.log(a.age) // 19
a.age // 18
a.age=19 // number 19

对于原型上的可枚举属性,Object.keys()不会去递归获取,for in会获取。

2 数据代理

即通过一个对象代理对另一个对象的访问和赋值!主要使用到了getter和setter

let a ={x:1}
let b= {y:2}
Object.defineProperty(a,'x',{
	get(){return a.x},
	set(value){a.x=value}
}
// 此时通过b对象可以对a对象x属性操作,b对象中有对a属性x的getter和setter
// a的x变化会影响b中的值,b中操作x会影响a中的x
// 两个对象关于x建立起了双向数据绑定关系

3 预编译

预编译主要注意点就是类型提升,包括var定义的函数和变量,函数和变量在用var定义时会出现类型提升,提升到当前作用域的最顶层
以下有几个注意点:

  1. 使用var定义的变量var a=2,定义部分提升
  2. 使用var定义的函数var a=function(){},定义部分提升
  3. 直接定义的函数function a(){},整体提升
  4. 提升按照顺序依次往下排列,后面的同名变量会覆盖前面的变量

示例:

function fn(a, c) {
    console.log(a);
    var a = 123
    console.log(a);
    console.log(c);
    function a() { }
    if (false) {
        var d = 678
    }
    console.log(d);
    console.log(b);
    var b = function () { }
    console.log(b);
    function c() { }
    console.log(c);
}
fn(1, 2)

预编译后结果为:

function fn(a, c) {
    function a() { }
    var d;
    var b;
    function c() { }

    console.log(a);//function
    a = 123
    console.log(a);//123
    console.log(c);//function
    
    if (false) {
        d = 678
    }
    console.log(d);//undefined
    console.log(b);//undefined
    b = function () { }
    console.log(b);//function
    console.log(c);//function
}
fn(1, 2)

输出:

[Function: a]
123
[Function: c]
undefined
undefined
[Function: b]
[Function: c]

4 函数调用中的this指向

明确一点即可:函数在与()结合时,前面若有调用对象,则函数内this指向该对象,否则指向window
示例:

var name = 222
var a = {
    name: 111,
    say: function () {
        console.log(this.name);
    }
}

var fun = a.say
fun() // 直接调用,指向window,222
a.say() // 调用前有a对象,指向a对象,111

var b = {
    name: 333,
    say: function (fun) {
        fun() // 传入的是函数体,然后该函数体被直接调用了,所以指向依然是window,222
    }
}
b.say(a.say) // b.say调用了,b.say中this指向b,接收一个参数是函数体,然后该函数体被直接调用了,直接调用所以指向依然是window,222
b.say = a.say
b.say() // 调用前有b对象

5 Promise详解

Promise拥有3个原型方法和多个静态方法

  • new Promise((resolve,reject)=>{处理逻辑})
    构造方法接收一个函数,该函数有两个入参用于改变promise的状态,前者为pending到ful后者为pending到rej

注意:Promise拒绝状态如果不捕获会抛出异常!捕获方法为then中的第二个参数回调函数或catch方法

原型方法

  1. then(回调1,回调2)
    可以处理Promise被接收或拒绝的情况,最多接收两个参数,且then函数的返回值与参数有关
    参数一:接收一个函数,用于Promise变为fulfilled状态时调用,该函数入参为完成值即resolve()的入参(如果入参不是函数会被转化成x=>x
    参数二:接收一个函数,当变为rejected状态时调用,入参为拒绝原因(如果入参不是函数会被转换成Thrower函数抛出错误,抛出的值为promise的reject()的入参)
    返回值:若then()函数的入参函数没有返回值(res)=>{},则返回一个接收状态的Promise,入参值为undefined(等价于:Promise.resolve(undefined))。若返回一个值,则该值作为接收状态的promise的入参值。若抛出一个错误,则错误信息作为拒绝状态的promise的入参值(等价于:Promise.rejected(error))。若返回接收或拒绝状态的Promise则无需解释。

  2. catch(回调)
    用来处理Promise被拒绝的情况,等同于:then(undefined,onRejected)

  3. finally(回调)
    用于在promise结束时无论如何一定会执行的回调函数,
    入参:为函数,该函数的的入参为空
    返回值:为原Promise的值,finally中若抛出异常则返回rejected的Promise对象,且回调函数入参是异常对象,可以使用catch捕获:.catch(e=>{})

静态方法

Promise.resolve()Promise.reject()返回的就是成功和失败的Promise对象

  1. all()
    race()类似,都是监控多个Promise。
    入参:接收一个可迭代对象,每个对象都必须为Promise,如果是常量会被Promise.resolve()封装,
    返回值:是一个新的Promise实例,当all的参数为空,返回的是成功的Promise,否则:所有成员都是成功时,为成功,且回调入参为结果数组。有一个成员为失败时,为失败,且回调入参为这个失败对象(失败对象是最先返回的那个失败对象)。

  2. race()
    入参:同all
    返回值:当参数为空数组时,状态为pending,当参数不为空,状态为最先返回的那个Promise的状态

  3. allSettled()
    入参:同all
    返回值:无论各项的返回为何,都将返回一个resolve状态的Promise,其回调函数的入参为一个数组,如果某项为成功返回:{"status":"fulfilled","value":"promise"},失败返回:{"status":"rejected","reason":"promise"}

Promise.allSettled([promise1,promise2,promise3,promise4]).then(function(args){
  console.log(args);
})
  /*
  result: 
  [
    {"status":"rejected","reason":"promise1"}, 
    {"status":"fulfilled","value":"promise2"},
    {"status":"fulfilled","value":"promise3"}, 
    {"status":"rejected","reason":"promise4"}
  ]
  */
  1. any()
    入参:同all
    返回值:除了所有Promise都返回失败这种情况会返回失败,且回调函数入参为失败对象的一个聚合(调用:.errors获得失败结果数组),其余情况都返回最快的那个成功Promise

6 创建对象的几种方式:Object.create/new Object/Object.assign

Object.create():用于从原型创建对象,该对象属性为空,原型上挂载源对象的属性,原型的原型指向Object。创建的新对象的原型指向接收的参数本身。

  1. 接受原型对象可创建出该原型对应的对象
  2. 接收普通对象创建出普通对象

new Object():返回一个新对象,该对象属性同原对象一样

  1. 接受普通对象返回普通对象本身
  2. 接收原型对象返回原型对象本身

new XXX():返回XXX的新对象,该对象的原型指向构造函数原型

Object.assign():接收两个对象,将后者属性合并到前者,返回的对象就是第一个参数的对象,对其作了修改!

使用new创建对象。相当于执行以下步骤:

// new Person()
var Obj = {};
Obj._proto_ =  Person.prototype();
Person.call(Obj);

可以通过Object.create(null)创建一个干净的对象,也就是没有原型,而 new Object()创建的对象是 Object的实例,原型永远指向Object的prototype

7 javascirpt字符串默认编码格式

默认采用UTF-16编码,一个字符占用2个字节,对于超过0xFFFF的编码占用四个字节

String.length()方法统计的是UTF-16编码单元数量!一个单元对应2字节

对于常用字符来说,一个单元长度就够了,对于超过一个编码单元,即超过两字节的是两个编码单元,即四字节。

进制转换

十进制:123
2进制:0b1010
8进制:01237
16进制:0x19FE

十进制转其他进制:

由于默认表示的数值都是十进制,所以转成其他进制使用字符串表示
调用的是Number对象的toString(进制)方法

var a = 11
a.toString(2) // 1011
a.toString(8)
a.toString(16)
11..toString(2) // 双点解析
(11).toString(2) // 括号解析

其他进制转十进制

调用parseInt(string,radix)函数,默认radix=10

parseInt("1011",2) // 11
parseInt("FF",16)
parseInt("066",8) // 54
parseInt("066") // 66

8 双点解析

对于常量类型,是没有办法调用方法的,需要先解析或者参与运算,自动包装成对象才行

11.toString(2) // 报错
let a = 11
a.toString(2) // 正确

或者使用() or ..来进行解析

(11).toString(2)
11..toString(2)

9 ?.和??运算符

?.:用来探测当前属性是否存在

let list = res.data.list // 当data不存在时会报错
let list = res && res.data && res.data.list // 一般常用方式
let list = res?.data?.list // ?.方式

??:用来判断当前值是否存在(除了null和undefined都是存在)

let a = a ? a : "" // a存在则为a否则为空,这里存在表示逻辑除了null、undefined、false、0其余都存在
let a = a ?? "" // a存在则为a否则为空,这里存在除了null和undefined都存在

10 Object禁止扩展preventExtensions

对一个对象禁止其新增属性:Object.preventExtensions(xxx)
此时xxx对象无法新增属性,如:xxx.a = 1失败

11 Object密封seal

该方法将一个对象进行密封,内部实现了两个步骤:先禁止扩展,然后所有属性configurable:false
此时,这个对象不可添加新属性,且原属性的特性不能再被更改,但是属性值如果可写是可以改变的

12 Object冻结freeze

该方法冻结一个对象,内部实现两个步骤:先密封,再将所有属性writable:false,即此时对象不可添加新属性,不可重新赋值原属性值,如果想深度冻结,需要进行迭代处理。

// 深度冻结
var deepFreeze =function (obj) {
	var allProps = Object.getOwnPropertyNames(obj); // 只会查找当前的对象下的所有属性,包括不可枚举
	// 同上:var allProps = Object.keys(obj);
	allProps.forEach(item => {
		if (typeof obj[item] === 'object') {
			deepFreeze(obj[item]);
		}
	});
	return Object.freeze(obj);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值