原生JS零魂之问(上)学习笔记‍

作为一个普通的JS初学者,从神三元大佬的知识梳理文章中受益匪浅,写下我的学习笔记吧。

JS数据类型

function test(person) {
    person.age = 26
    person = {
      name: 'hzj',
      age: 18
    }
    return person
  }
  const p1 = {
    name: 'fyq',
    age: 19
  }
  const p2 = test(p1)
  console.log(p1) // { name: 'fyq', age: 26 }
  console.log(p2) // { name: 'hzj', age: 18 }

test函数中的实参personp1对象在堆中内存地址的copy,调用person.age = 26改变了p1的值,但随后person又被重写覆盖了,变成了另一块内存空间的地址,并且在最后将这另外一份内存空间的地址返回,赋给了p2

研究一下 前五个貌似是对象,因为他们拥有方法,但他们是不可变的?

数字、字符串、布尔值并不是对象,但是它们却拥有属性和方法。这是因为在引用它们的属性和方法时会分别通过调用new Number()new String()new Boolean()包装对象来转换成对象,该对象继承了对应的方法来处理属性的引用,一旦引用结束,便会销毁这个临时对象。nullundefined没有包装对象,访问它们的属性会报类型错误。

    console.log(typeof 1);  //number
    console.log(typeof new Number(1)); //object
    1 === new Number(1) //fasle

这里把1包装成一个对象,这就是原始类型和包装对象的区别。

    let x = 32;
    console.log(x.toString(2));  //100000
    // 创建object实例 调用实例方法 销毁实例

方法和属性也可用于原始值,因为JS在执行方法和属性时将原始值视作对象。简单数据类型不能添加属性,但是除了nullundefined,其他的都可以访问属性,所以他们拥有对象的特征,但其实还是简单数据类型而非对象。

JS精度损失

console.log(0.1 + 0.2); // 0.30000000000000004

JS不分整型和浮点型,两个浮点数相加,转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉导致精度损失。

BigInt

在JS中,所有的数字都以双精度64位浮点格式表示,这导致JS中的Number无法精确表示非常大的整数,它会将非常大的整数四舍五入,JS中的Number类型只能安全地表示-9007199254740991(-(2^53-1))9007199254740991((2^53-1)),任何超出此范围的整数值都可能失去精度。

    const theBiggestInt = 9007199254740991n
    console.log(theBiggestInt, typeof theBiggestInt); // 9007199254740991n 'bigint'
    console.log(theBiggestInt + 1n);      // 9007199254740992n
    console.log(theBiggestInt * 10n);     // 90071992547409910n

JS类型装换

===叫做严格相等,是指:左右两边不仅值要相等,类型也要相等 叫做严格相等。==不像===那样严格,对于一般情况,只要值相等,就返回true,但==还涉及一些类型转换。

对象转原始类型
// 优先调用toPrimitive,最后调用toString
 var obj = {
     value: 3,
     valueOf() {
        return 4;
     },
     toString() {
       return '5'
     },
     [Symbol.toPrimitive]() {
       return 6
     }
   }
   console.log(obj + 1); // 输出7 

闭包

  • 函数内部嵌套函数 包含被引用变量(函数)的对象。
    闭包产生的本质就是,当前环境中存在指向父级作用域的引用。
var f3;
function f1() {
  var a = 2
  f3 = function() {
    console.log(a);
  }
}
f1();
f3(); // 2

调用f1()f3()赋值,此时f3()拥有windowf1f3本身这几个作用域的访问权限,变量f3存在着父级作用域的引用,因此产生了闭包。

JS实现继承

  function Parent () {
    this.name = 'parent';
    this.play = [1, 2, 3];
  }
  function Child() {
    Parent.call(this);
    this.type = 'child';
  }
  Child.prototype = Object.create(Parent.prototype);
  Child.prototype.constructor = Child;
面向组合继承

面向组合就是先设计一系列零件,然后将这些零件进行拼装,来形成不同的实例或者类。代码干净,复用性也很好。这就是面向组合的设计方式。

function drive(){
  console.log("wuwuwu!");
}
function music(){
  console.log("lalala!")
}
function addOil(){
  console.log("哦哟!")
}

let car = compose(drive, music, addOil);
let newEnergyCar = compose(drive, music);

附上原文链接:( 建议收藏 )原生JS灵魂之问, 请问你能接得住几个?(上)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值