JavaScript学习笔记17

一、包装类

引用值就是一种对象(泛泛的概括类对象),包括数组、函数、对象。在内存里面存储。


原始值不能有属性和方法,引用值才可以有


但是经过包装类,原始值就能有属性和方法


通过原始值访问属性和方法,系统为了让语法好用,不报错,系统会帮我们进行一个js内部机制包装类

<script>
        var str = "abc";
        //new String("abc").length
        console.log(str.length);
    </script>

思路:即隐式的new String构造出一个字符串对象,然后把字符串内容与原来保持一致new String(“abc”),因为我们进行了str.length操作,那么他也加上.length,变成了隐式new String,变成了隐式new String(“abc”).length


这里虽然写的是console.log(str.length),实际上执行的是console.log(new String(“abc”).length)


这样隐式的执行过程就是包装类



<script>
        var num = 123;
        num.abc = "abc";
        //new Number(num).abc="abc"--->delete
        //
        //new Number(num)..abc
        console.log(num.abc);//undefined
    </script>

思路:
当 num.abc = “abc”时,系统会进行包装类,隐式的 new
Number(num).abc = “abc”;

执行完这一步以后就会 delete 掉这个隐式的值,并不保


等下一步又遇到 num.abc 时,又隐式的 new 了一个 number。

但是这个和上一个是两个 new Number,是两个彼此独立的对象。



new.Number(123).abc 和 var num = new Number(123); num.abc 是一样的



二、原型

任何函数上都有原型,包括构造函数,这是一个构造函数,原型需要基于构造函数,没有原型的构造函数没有意义,任何一个函数都会有prototype

<script>
        Person.prototype.lastName = "deng";

        function Person() {
            //var this={
            //
            // __proto__: Person.prototype
            //}
        }
        var person = new Person();
        console.log(person.lastName); //deng
    </script>



三、create

Object.create();是创建的对象,对象必须要有原型,Object.create();需要指定创建对象的原型是谁,括号里面就要填谁(所以括号里面一定要填值)

<script>
        var demo = {
            lastName: "deng"
        }
        var obj = Object.create(demo);
        obj = {
            __proto__: demo
        }
    </script>

在这里插入图片描述

Object.create(prototype,definedProperty)还能填第二个参数。

第一个填的prototype表示你的原型是谁,第二个参数definedProprety是特性(可读可写都是特性)



<script>
        var num = 123;
</script>

在这里插入图片描述

这个num算window的属性。写在全局的属性

一旦经历了var的操作,所得出的属性window,这种属性叫做不可配置的属性,delete不掉

直接增加的属性叫可配置属性,delete只能删除可配置的属性



<script>
        var obj = {

        }
        obj.num = 234;
</script>

在这里插入图片描述



直接在控制台操作对比,发现var 过的属性是不可配置的属性,delete不掉

在这里插入图片描述
在这里插入图片描述



四、this call

  • 1、预编译 this==>window
  • 2、谁调用的,this指向谁
  • 3、call和apply能改变this指向
  • 4、全局this==>window



注释掉的是预编译的过程

    <script>
        function test() {
            var num = 123;

            function a() {

            }
        }
        test() -- > AO {
            arguments; {}this: window,
                num: undefined,
                a: function() {}
        }
    </script>


test();完全等于test.call();执行

其实test()执行会内部转换成test.call();执行

<script>
        function test() {
            console.log(this);
        }
        test();
</script>

在这里插入图片描述



如果我们在test.call();里面传值,第一个值就会作为函数执行时的this环境

 <script>
        function test() {
            console.log(this);
        }
        // test();
        test.call({
            name: "deng"
        });
        // test()-->AbortController{
        //     arguments:{},
        //     this:{name:"deng"},
        //     num:undefined,
        //     a:function(){}
        // }
    </script>

在这里插入图片描述



 <script>
        var name = "window";
        var obj = {
            name: "obj",
            say: function() {
                console.log(this.name);
            }
        }
        obj.say(); //obj
</script>
<script>
        var name = "window";
        var obj = {
            name: "obj",
            say: function() {
                console.log(this.name);
            }
        }
        obj.say.call(window);//window
</script>

obj.say.call(windwo);有call就打破一切规则,call()里面传的是谁,就是谁



<script>
        var name = "window";
        var obj = {
            name: "obj",
            say: function() {
                console.log(this.name);
            }
        }
        var fun = obj.say;
        fun(); //window
    </script>

var fun=obj.say相当于var fun=say:function(){}里面的函数体

fun();相当于让say:function 在这函数的全局范围内自调用,不是谁调用的,就只能走预编译,this就是window



<script>
        var name = "window";
        var obj = {
            name: "obj",
            say: function() {
                console.log(this.name);
            }
        }
        var fun = obj.say;
        fun.call(obj);//obj
    </script>



想让Person实现Stundent的功能

<script>
        function Person(name, age) {
            this.name = name;
            this.age = age;
        }

        function Student(name, age, sex) {
            //var this=Object.create(Student.prototype);
            this.name = name;
            this.age = age;
            //上面两句可以简化Person.call(this,name,age);
            this.sex = sex;
        }
        var student = new Student("cheng", 18, "male");
    </script>

五、闭包

闭包表象:一个函数套着另外一个函数,你把被嵌套的函数保存到套他的函数外面(a套着b,你把b弄出a里面),就形成了闭包(不一定要return)

下面两种方法都能实现闭包

<script>
//一

        function a() {
            function b() {

            }
            return b;
        }
        
//二
        var obj = {};

        function a() {
            function b() {

            }
            obj.fun = b;
        }
    </script>



<script>
        var obj = {};

        function a() {
            var aa = 123;

            function b() {
                console.log(aa);
            }
            obj.fun = b;
        }
        a();
    </script>

在这里插入图片描述



 <script>
        var a = 132;
        //this call
        // Go {
        //     a: 123
        // }
        // AO {
        //     a: undefined
        // }

        function test() {
            a = 1;
            var a;
        }
        test();
    </script>


六、构造函数

通过构造函数构造对象的时候用 new,执行函数的时候就不用 new
构造对象必须是 new 加上构造函数执行(如 person();)才能构造出对象
有了 new 之后,才会发生两步隐式变化(var this = {}; return this)

<script>
        function Person() {
            //var this={}
            this.name = "abc";
            this.age = 123;
            //return this;
        }
        var person = new Person();
    </script>

没有var person=new Person();只Person会走预编译,此时this指向window



私有化属性看不到var money=100;
外部看不到 var money


下面这个就是闭包的应用
 <script>
        function Person() {
            //var this={
            // 
            //   makeMoney:function(){}
            //   offer:function(){}   
            // }
            var money = 100;
            this.name = name;
            this.makeMoney = function() {
                money++;
            }
            this.offer = function() {
                    money--;
                }
                //return this;
        }
        var person = new Person();
    </script>


<script>
        var inherit = (function() {
            var F = function() {};
            return function(Target, Origin) {
                F.prototype = Origin.prototype;
                Target.prototype = new F();
            }
        }());
    </script>

立即执行函数执行完就成下面这样了

<script>
        var inherit = function(Target, Origin) {
            F.prototype = Origin.prototype;
            Target.prototype = new F();
        }
    </script>


在这里插入图片描述

数组不等于数组,因为里面的地址不一样



七、克隆

<script>
        var obj = {
            name: "abc"
        }
        var obj1 = {

        }
        for (var prop in obj) {
            obj1[prop] = obj[prop];
        }
    </script>

浅克隆:当拷贝引用值的时候就不行了

<script>
        var obj = {
            name: "abc",
            card: ['visa', 'master']
        }
        var obj1 = {

        }
        for (var prop in obj) {
            obj1[prop] = obj[prop];
        }
    </script>

这样浅克隆,克隆的是地址,缺点是你改我也改


深度克隆解决的就是引用值

<script>
        var obj = {
            name: "abc",
            wife: {
                name: "xiaoxu",
                son: {
                    name: "xiaowen"
                }
            }
        }
        var obj1 = {

        }
        for (var prop in obj) {
            obj1[prop] = obj[prop];
        }
    </script>

深度克隆不拷贝地址,是新建一个来拷贝对象

<script>
var obj1 = {
            name: obj.name,
            wife: {
                name: obj.wife.name,
                son: {
                    name: obj.wife.son.name
                }
            }
        }
</script>


在这里插入图片描述

null和undefined不能和数字进行比较,不会进行类型转换,他们不作为比较值存在



下面考私有化变量

在这里插入图片描述

打印 1,2,1



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述
在这里插入图片描述



例:选择你熟悉的一种方式实现 JavaScript 对象的继承

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值