JS高级01

基于Ansys Fluent 的颗粒分离/过滤解决方案 过滤是指通过特殊装置将颗粒移除,将流体提纯净化的过程。过滤的方式很多,应用的物系也很广泛,固-液、固-气、大颗粒-小颗粒等。 阅读详情

JS高级

预解析内容

  • 代码段是指一个script标签就是一个代码段。JS代码在执行时,是一个代码段一个代码段执行。
  • 代码段是相互独立的上面的代码段报错了,不会影响下面的代码段
  • 可以在下面代码段中使用上面代码段中的数据!
    <script>
        var a = '我是第一个代码段中的a';
        console.log(b);//b is not defined
        //在上面的代码段里不能使用下面定义的数据
    </script>

    <script>
        var b = '我是第二个代码段中的b';
        console.log(a);//打印'我是第一个代码段中的a'
        //在下面的代码段里能使用上面定义的数据
    </script>

什么是预解析

  • 浏览器在执行JS代码的时候会分成两个部分操作:预解析和逐行执行代码
  • 也就是浏览器不会直接执行代码,而是加工处理后再执行
  • 这个加工处理的过程就是预解析

预解析会做什么?

  • 预解析期间会提升变量,在代码段中加var 的变量 和 function声明的函数会提升到代码段的最前面,注意:变量提升只提升声明,函数提升的是函数整体!
  • 除了代码段中的全局数据会提升外,函数体内部的局部变量也会提升,注意:局部变量在函数内部提升只提升声明。
  • 结论:预解析会变量提升,变量只提升声明,函数提升整体!
  • 注意:提升的同名变量名和函数名,函数会覆盖变量,函数在JS中是一等公民优先级高
  • 注意:当函数名重复声明并赋值的话 只会提升第一个

预解析练习题

  • 题目1
    <script>
        //预解析提升:
        //var a; fn(){};
        console.log(a);//undefined
        var a = 110;   //给a 赋值为110
        console.log(a);//110

        fn();          //调用fn函数 打印 我是一个fn函数
        function fn(){
            console.log('我是一个fn函数');
        }
    </script>
  • 题目2
    <script>
        //预解析提升:
        //var g;
        g();           //g提升后值为 undefined 所以结果为g is not a function
        var g = function(){ //g 是一个变量 不是函数
            console.log('g函数执行了..');
        }
    </script>
  • 题目3
    <script>
        //预解析提升:
        //var i;
        console.log(i);//undefined
        for(var i = 0; i < 10; i++){}//循环给i赋值
        console.log(i);//i = 10
    </script>
  • 题目4
    <script>
        //预解析提升:
        //var a; fn(){};
        //var b; var a; var c;
        var a = 666;       //给全局变量a赋值 由undefined变为666
        fn();              //调用函数
        function fn() {
            var b = 777;   //给局部变量b赋值 由undefined变为777
            console.log(a);//打印 und
            console.log(b);//打印 777
            console.log(c);//打印 und
            var a = 888;
            var c = 999;
        }
    </script>
  • 题目5
    <script>
        //预解析提升:
        //var value; function value(){}
        console.log(value); //value由und 变为value函数体
        var value = 123;    //value由函数体变为123
        function value() {
            console.log('我是value函数...');
        }
        console.log(value); //打印123
        //结论:提升的同名变量名和函数名,函数会覆盖变量,函数在JS中是一等公民优先级高
    </script>
  • 题目6
    <script>
    //预解析提升:
        console.log(a);//a 没有加var 不提升 报错 a is not defined
        a = 666;
        console.log(a);//上面代码报错下面代码不执行
    </script>
  • 题目7
    <script>
    //预解析提升:
    //fn(){};
        function fn(){
            console.log(a);//找a 没有a  a is not defined
            a = 666;       //代码是从上到下执行的 没有运行到这一行 如果运行到这一行的话 会在VO中存一个 a = 666
            console.log(a);//不执行
        }
        fn();
        console.log(a);   //不执行
    </script>
  • 题目8
    <script>
    //预解析提升:
    //fn(){}
        function fn(){
            a = 110;
        }
        console.log(a); //函数没有执行 找不到a a is not defined
    </script>
  • 题目9
    <script>
    //预解析提升:
    //gn(){}
    //var k;
        gn();           
        function gn(){
            var k = 123;
            console.log(k); //123
        }
        console.log(k);     //k is not defined
    </script>

执行上下文

  • 全局执行上下文和局部执行上下文
  • 当全局代码执行时,就会产生一个全局的执行上下文,EC(G);
  • 当函数代码执行时,就会产生一个局部的执行上下文,EC(Fn)。只要调用一个函数,就会产生一个局部执行上下文。调用100个函数,就会产生100个执行上下文。
  • 在JS代码在执行时,肯定会先执行全局代码,就会产生ECG,这个ECG就要入栈。当我们调用一个函数,就会产生一个EC,这个EC就要入栈,当函数调用完毕后,EC就要出栈,又进入ECG,当全局代码执行完毕后,ECG也要出栈。
    <script>
        /*
            在JS代码在执行的时候会先执行全局代码,执行全局代码就会产生一个ECG,这个ECG就要入栈
            当我们调用函数的时候就会产生一个EC这个EC就要入栈,当函数调用完毕,就会出栈,又进入ECG
            当全局代码执行完毕后,ECG也要出栈。
        */
        /*
             ECG在执行代码之前会预解析然后把全局定义的变量函数放入VO(GO),GO中包括了内置的方法,window,以及自己声明的全局数据
             作用域链:ECG的作用域链就是VO本身
             
             ECF在执行代码解析前会创建一个AO对象AO中包含形参,arguments,函数定义和指向函数对象,定义的变量
             作用域链:ECF作用域链由AO和父级VO组成,查找数据会一层一层查找
        */
         /* 
            在函数内部不加var定义的变量为全局变量,全局变量只会保存在VO中
        */
    </script>

    <!-- <script>
        //原题
        var n = 110;
        console.log(n);
        console.log(window.n);
        m = 220;
        console.log(m);
        console.log(x);
    </script>

    <script>
        //分析
        //var n;
        //n = 110;
        var n = 110;
        console.log(n);//110
        console.log(window.n);//全局代码会放在GO中 GO就是window 所以n=110
        m = 220;
        console.log(m);//不加var的全局代码不会提升。m=220
        console.log(x);//x没有声明,x is not defined
    </script> -->



    <!-- <script>
        //原题
        var a = 1;
        var b = 'hello';
        function fn() {
            console.log('fn...');
        }
        var arr = ['a', 'b', 'c'];
        var obj = { name: 'wc', age: 100 }
    </script>

    <script>
        //分析
        //var a; var b; fn(){}; arr; obj;
        var a = 1;
        var b = 'hello';
        function fn() {
            console.log('fn...');
        }
        var arr = ['a', 'b', 'c'];
        var obj = { name: 'wc', age: 100 }
    </script> -->



    <!-- <script>
        //原题
        function fn(a) {
            console.log(a);
        }
        fn(110);
        console.log(a);
    </script> -->

    <!-- <script>
        //分析
        //fn(){};
        //var a;
        function fn(a) {    //函数形参(局部变量)变为110
            console.log(a); //110
        }
        fn(110);
        console.log(a);
    </script> -->



    <!-- <script>
        //原题
        var arr = [11, 22];
        function fn(arr) {
            arr[0] = 100;
            arr = [666];
            arr[0] = 0;
            console.log(arr);
        }
        fn(arr);
        console.log(arr);
    </script> -->

    <!-- <script>
        //分析
        //arr; fn(){}; 
        //arr; 
        var arr = [11, 22];//栈地址 0x666
        function fn(arr) { //给形参arr 赋值为 0x666
            arr[0] = 100;  //0x666指向的堆 数据变为[100,22];
            arr = [666];   //把新堆[666]的地址0x888赋值给 形参arr 此时形参中的arr指向了 0x888
            arr[0] = 0;    //修改ox888中的数据 ox888指向的堆的数据由[666]变为[0]
            console.log(arr); // 打印ox888堆中的数据 [0]
        }
        fn(arr);//形参arr 赋值为 0x666
        console.log(arr); //打印全局执行上下文中的arr 它指向ox666 数据为[100,22]
    </script> -->



    <!-- <script>
        //原题
        var a = 1;
        var b = 1;
        function gn() {
            console.log(a, b);
            var a = b = 2;
            console.log(a, b);
        }
        gn();
        console.log(a, b);
    </script> -->

    <!-- <script>
        //分析
        //var a; var b; gn(){}; 
        //var a;
        var a = 1;
        var b = 1;
        function gn() {
            console.log(a,b); //a 为und  b 没有提升在AO找不到 就去父级VO中找 父级VO中有b = 1 所以und 1
            var a = b = 2;
            console.log(a,b); //a 赋值为2 b赋值为2 所以父级中的b 由1 变成了2
        }
        gn();
        console.log(a, b);  //打印ECG中的a,b结果为:1,2
    </script>  -->



    <!-- <script>
        //原题
        var a = 1;
        var obj = { uname:'wangcai'}
        function fn(){
            var a2 = a;
            obj2 = obj;
            a2 = a;
            obj.uname = 'xiaoqiang';
            console.log(a2);
            console.log(obj2);
        }
        fn();
        console.log(a);
        console.log(obj);
    </script> -->

    <!-- <script>
        //分析
        //var a; obj; fn(){}; obj2
        //var a2; 
        var a = 1;
        var obj = { uname: 'wangcai' }
        function fn() {
            var a2 = a; //找a a在VO中值为1 赋值给a2 a2为1
            obj2 = obj; //把obj的地址0x666复制给了 obj2
            a2 = a;     //又把 VO中的1 赋值给了 a2
            obj.uname = 'xiaoqiang'; //0x666 中的wangcai变为了xiaoqiang 
            console.log(a2);        //打印a2 为1
            console.log(obj2);      //打印obj2 为ox666中的xiaoqiang
        }
        fn();
        console.log(a); //打印VO中的a 为1
        console.log(obj);//打印obj 为xiaoqiang
    </script> -->


    <!-- <script>
        //原题
        var a = [1,2];
        var b = a; //b 和 a 指向同一个堆
        console.log(a,b); //[1,2] [1,2]
        b[0] = 110; //[110,2]
        console.log(a,b);//[110,2] [110,2]
    </script> -->

    <!-- <script>
        //原题
        var a = [1,2];
        var b = [1,2];
        console.log(a == b);//false == 比较的是地址 不同的堆 地址是不可能一样的
        console.log(a === b);//false
    </script> -->

    <!-- <script>
        //原题
        var a = [1,2];
        var b = a;
        console.log(a == b);//a 和 b指向同一个堆 所以为true
        console.log(a === b);//a 和 b指向同一个堆 所以为true
    </script> -->

    <!-- <script>
        //原题
        console.log(a,b);//a变量提升本身应该为und 但是b没提升 b为 b is not defined 所以直接报错
        var a = b = 3;
    </script> -->

    <!-- <script>
        //原题
        var a = {m:666};
        var b = a;//把a的地址赋值给b
        b = {m:888};//把新地址赋值给b b的地址变了
        console.log(a);//a的值还是m:666没变化
    </script> -->

    <!-- <script>
        var a = {n:12};
        var b = a;
        b.n = 13;
        console.log(a.n);//13
    </script> -->

    <!-- <script>
        console.log(a); //a is not defined
        a = 110;
    </script> -->

    <!-- <script>
        var m = 1;
        n = 2;
        console.log(window.m);//1
        console.log(window.n);//2
    </script> -->

    <!-- <script>
        function fn(){
            var a = 111;
        }
        fn();
        console.log(window.a);//undefined
    </script> -->

    <!-- <script>
        var a = -1;
        if(++a){      //++a的值为新值 为0  0 为false
            console.log('666');// 不执行 
        }else{
            console.log('888');//打印888
        }
    </script> -->

    <!-- <script>
        //var a; var b;
        console.log(a,b);//und und
        if(true){
            var a = 1;
        }else{
            var b = 2;
        }
        console.log(a,b);//1 und
    </script> -->

    <!-- <script>
        var obj = {
            name:'wc',
            age:18
        }
        //in 为运算符 判断一个属性是否属于某个对象
        console.log('name' in obj);//true
        console.log('score' in obj);//false
    </script> -->

    <!-- <script>
        //var a;
        var a;
        console.log(a);//und
        if('a' in window){
            a = 110;
        }
        console.log(a);//110
    </script> -->

    <!-- <script>
        //var a;
        console.log(a);//und
        if('a' in window){
            var a = 110;
        }
        console.log(a);//110
    </script> -->

    <!-- <script>
        //var a; fn(){};
        //var a;
        var a = 100;
        function fn(){      //函数内部有a 并且加var了 所以提升 先提升再执行 
            console.log(a); //所以还没有执行到return 打印undefined
            return;
            var a = 100;
        }
        fn();
    </script> -->

    <!-- <script>
        //提升
        //var n; foo(){};
        //foo中把全局变量中的n的值改成了200
        var n = 100;       //这两个n是同一个n
        function foo(){
            n = 200;       //这两个n是同一个n
        }
        foo();//调用完函数后把全局变量中的n的值改成了200
        console.log(n);//打印全局变量n = 200
    </script> -->

    <!-- <script>
        //fn(){}; 
        //var a;
        function fn(){
            var a = b = 100;//var a = 100; b = 100; b在AO中没有定义
        }                   //所以到VO中找 但是VO中也没有 所以报错        
        fn();
        console.log(a);//100
        console.log(b);//b is not defined
    </script> -->

    <script>
        //var n; fn(){}; gn(){};
        //
        var n = 100;//全局变量n = 100
        function fn(){
            console.log(n);//打印n 自己里面没有n 按照作用域链到父级找
                           //找到GO中全局变量n = 100
        }
        function gn(){
            var n = 200;
            console.log(n);//200
            fn()//fn()在全局代码段中调用 父级是GO 
        }
        gn();//200 100
        console.log(n);//100
    </script>

深入变量

加var变量和不加var变量的区别:

  • 加var的全局变量会在预编译期间提升到代码段的最前面,不加var的变量不会提升。
  • 加var的变量有可能是全局变量,也有可能是局部变量,不加var的变量只可能是全局变量。
  • 加var的局部变量不会作用到window的属性。

let声名的变量:

  • let声明的变量不会提升
  • let声明的变量不会作用到window的属性
  • let和{}配合产生局部作用域 局部作用域外部访问不到{}里面的数据

const声明的变量:

  • const主要声明常量,const声明必须初始化赋值
  • const声明的变量不可以改变
  • const声明的变量不会提升
  • const和{}配合会形成块级作用域,块里面的数据外部访问不到
  • const声明的常量也不会挂载到GO上

闭包

什么是闭包

  • 闭包就是一个不能被销毁的栈空间(内存)局部EC
  • 一个普通函数可以访问外层作用域的自由变量,那么这个函数就是一个闭包
  • 闭包的作用:
  • 延长闭包中数据的生命周期,所对应的内存会一直存在不会被释放掉,造成内存泄漏
  • 外面想去访问里面的数据,是访问不了的

函数是一等公民

  • 在JavaScript中,函数是非常重要的,并且是一等公民 高阶函数就是函数可以作为另一个函数的参数,也可以作为另外一个函数的返回值来使用

IIFE

IIFE就是立即函数调用表达式的意思。

    <script>
        //IIFE 就是立即调用函数表达式的意思
        //函数后加小括号 然后整体用小括号包起来
        //01(function say(){ console.log('hello');}())
        //02+function say(){ console.log('hello');}()
        //03-function say(){console.log('hello');}()
        //04!-function say(){console.log('hello');}()
        //05(function say(){console.log('hello');})()
        //如果IIFE前面是return +-!()可以不写
        //也就是IIFE是函数内部的return后的函数的时候 +-!()可不写
    </script>

高阶函数:

  • 一个函数的参数是函数 或 他的返回值是函数,那么这个函数就是高阶函数。
  • 自己手写的高阶函数 函数的参数是一个函数
function fn(a){
	a();
};
function gn(){
	console.log(666);
}
fn(gn);
  • 数组中的高阶函数
  • filter 过滤函数返回值是过滤得到的新数组
  • map 映射函数
  • forEach快速遍历
  • find查找函数 返回的是找的到元素 找不到返回und
  • findIndex 查找函数 返回的是 数组下标 找不到返回-1
    <script>
        let nums = [2, 23, 77, 45, 3, 8, 10];
        // nums.filter() 表示调用函数
        // nums.filter(function(){}) 把一个匿名函数作为函数的实参 传给filter
        //filter是JS中内置好的高阶函数
        //filter的返回值是一个数组
        //匿名函数作为filter高阶函数的实参 这个匿名函数也有自己的形参item item 表示数组的每一项
        //就相当于 匿名函数的形参item 在匿名函数里的arguments 包含了所有的实参
        let newArray = nums.filter(function (item) {
            // return true; 表示把item中的每一项都放到新数组中
            return item % 2 == 0;
        })
        console.log(newArray);
    </script>
    <script>
        //map 映射 对数组中的每一项进行加工
        let nums1 = [2, 23, 77, 45, 3, 8, 10];
        let newArray1 = nums1.map(function(item){
            return itme * 10;
        })
        console.log(newArray1);
    </script>
    <script>
        //forEach
        let nums2 = [2, 23, 77, 45, 3, 8, 10];
        let newArray2 = nums2.forEach(function(item){
            console.log(item);
        })
    </script>
    <script>
        //find
        let nums3 = [2, 23, 77, 45, 3, 8, 10];
        let itemm = nums3.find(function(item){
            return item === 8;
        })
        console.log(itemm);//返回的是查找的元素 找不到返回的是 und
    </script>
    <script>
    	//findIndex
        let nums4 = [2, 23, 77, 45, 3, 8, 10];
        let itemm = nums4.findIndex(function(item){
            return item === 3;
        })
        console.log(itemm);//返回的是 数组下标
    </script>

this指向与this相关

默认绑定

  • 默认绑定就是独立函数调用,可以理解为用window调用了这个函数只不过没有加.所以独立函数调用中this为window

隐式绑定

  • 独立函数调用,把对象内的方法地址传给外部变量,通过外部变量加()调用对象里面的方法,此时方法里的this表示的是window
  • 通过对象.方法名+()调用对象内部的方法,方法中出现的this就看.前面的是谁,this就代表了谁。

显示绑定

  • 函数也是对象 上面有几个默认的方法 通过call apply bind 可以改变this指向
    使用方法:想要改变this指向的函数名.call(想要指向的东西);
    使用方法:想要改变this指向的函数名.apply(想要指向的东西);
    使用方法:想要改变this指向的函数名.bind(想要指向的东西);
    注意:
    call 和 apply 不仅可以显示绑定this 而且还会让函数执行
    call 会将传入想要指向的东西 包装成一个新的对象返回
    bind 显示绑定this 不会让函数执行 返回一个绑定this 之后新函数

new绑定

  • 使用new创建一个对象
    第一步这个new会在类中生成一个空的对象(堆)
    第二步这个new中会生成一个this 这个this指向了这个堆
    第三步使用类生成的这个对象也会指向这个堆

规则优先级

  • 默认规则的优先级最低
  • 显示绑定优先级高于隐式绑定
  • new绑定优先级高于隐式绑定
  • new绑定优先级高于隐式绑定
  • new绑定优先级高于bind
  • new绑定和call、apply是不允许同时使用
  • new绑定可以和bind一起使用,new绑定优先级更高

忽略显示绑定

  • 如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定会被忽略,使用默认规则

箭头函数中this指向

  • 箭头函数中的this指向外面一层。

面向对象

创建对象的几种方式

    <script>
        
        创建对象的几种方式:
            字面量法:
                let obj = {};

            new方法:
                let obj = new Object(); new一个Object类 生成一个obj对象 //Object叫类也叫构造器
                let str = new String(); new一个String类 生成一个str对象 //String叫类也叫构造器

            工厂模式:
                function Person(name,age){
                    let obj={};
                    this.name = name;
                    this.age = age;
                    return obj;
                };
                let cc = Person('陈城',21);
                let gh = Person('高涵',22);
                打印出它的类时,都是Object 每个对象都是Object的实例
                这种方式 生成的对象 对应的全部都是 Object类 不能很真实的反应对象所对应的类

            构造函数法:
                创建一个手机类
                function Phone(name,price){
                    this.name = name;
                    this.price = price;
                }
                let mi = new Phone('小米',1999);
            new做了什么:
                在构造器的内部创建了一个新的对象
                让构造器中的this指向这个对象
                执行构造器中的代码
                如果构造器没有返回对象,那么返回这个被创建的新的对象
                这个对象内部的prototype属性会被赋值为该构造函数的prototype属性
            
            构造器+原型创建对象
                把共有的属性放到原型上
                    function Player(name){
                        this.name = name;
                    }
                    Player.prototype.game() = function(){
                        console.log(this.name + '开始比赛');
                    }
                    let qiaodan = new Player('乔丹');
                    qiandan.game();

            位于类上的属性叫做:静态属性
                    
            判断 一个对象是否属于 一个类 对象.instanceof(类)
            str.instaceof(Number);//false
        
    </script>

私有属性和公有属性

    <script>
        /* 
            一切都是对象
            对象是属性的无序集合
            原型链:
                查找对象上的属性,如果对象本身的私有属性中没有,那么会沿着__proto__到创建对象的构造器的原型对象中找
                每一个对象都有一个__proto__那么构造器的原型对象也有一个__proto__ 在创建对象的构造器的原型对象中
                还是找不到的话 也会沿着__proto__去Object 的原型对象中找 找不到的话 继续沿着__proto__找 找到null
                还找不到就报错,这个沿着__proto__查找属性的链 就叫原型链。

                每一个函数(构造器中都有一个prototype属性) 这个prototype指向这个构造器的原型对象
                每一个对象都有一个__proto__的属性 这个属性指向 创建它的构造器的原型对象
                原型对象中不仅有__proto__而且还有一个constructor指向创建原型对象的构造器
                构造器的prototype指向和这个构造器生成的对象中的__proto__指向的是同一个原型对象
                构造器的prototype指向创建的原型对象
                所有函数的默认原型都是Object的实例
                通过__proto__可以向上查找属性 
        */
    </script>
    <script>
        let arr2 = new Array('a','b','c');
        console.log(arr2);
        console.log(arr2.__proto__);//Array 原型对象
        //打印创建出arr2这个对象的原型对象 也就是打印Array的原型对象
        console.log(arr2.__proto__.__proto__);//Object 原型对象
        //每一个对象都有一个__proto__ 那么 Array的原型对象的__proto__也指向创建Array的原型对象的原型对象 这个对象为Object
        
        console.log(Array.prototype == arr2.__proto__);
        console.log(arr2.__proto__.constructor == Array);//true 
        //每一个原型对象上不仅有一个__proto__ 还有一个constructor 这个constructor 指向这个构造器

        console.log(arr2.__proto__.constructor);//Array 原型对象
    </script>

精细化设置对象中的属性

    <script>
        /* 
        精细化设置对象中的属性
            数据属性描述符 configurable enumerable writable value
            Object.defineProperty(目标对象,作用的属性,{
                value:设置的属性值,
                configurable:是否可以删除,//默认都是true ture表示可以删除
                enumerable:是否可以枚举,//默认都是true ture表示可以枚举
                writable:是否可以重新赋值//默认都是true ture表示可以修改
            })
            存取属性描述符 get set
            get:当获取属性的时候会执行的函数 默认为undefined
            set:当设置属性的时候会执行的函数 默认为undefined
            Object.defineProperty(目标对象,作用的属性,{
                configurable:false,
                enumerable:false,
                get:function(){
                    console.log('get...');
                    return this._address;
                }
            })
        */
    </script>
    <script>
        /* 
        get作用:
            获取器:当调用添加精细化添加的属性 那么就会自动调用defineProperty中的get 返回对象中的属性
        set作用:
            设置器:当给精细化属性重新赋值的时候,就会自动调用set函数 把修改的值 赋值给对象中的属性
        */
        let obj = {
            name:'sc',
            age:22,
            _address:"商丘"
        }
        Object.defineProperty(obj,'address',{
            configurable:false,
            enumerable:false,
            get:function(){         //获取器 当调用address 就执行里面的函数
                // console.log('get..');
                return this._address;//可以是对象的任意属性
            },
            set:function(value){    //设置器 当修改address 就执行里面的函数 把_address的值修改为 传入的address的值
                // console.log('set...');
                this._address = value;
            }
        })

        console.log(obj.address);//商丘
        obj.address = '博爱'; //修改对象中的属性值 把精细化属性值 "博爱" 赋值给对象中的属性值 this._address = value;
        console.log(obj._address);//博爱
    </script> 
    <script>
        /* 
        给多个属性精细化设置
        Object.definproperties(obj,{
            作用的属性:{

            },
            作用的属性:{

            }
        })
        */
       let obj = {
           _age:18,
           _address:'香港'
       }
       Object.defineProperties(obj,{
           name:{
               value:'修狗',
               configurable:true,
               enumerable:true,
               writable:true
           },
           address:{
               configurable:true,//可以删除
               enumerable:true,//可以枚举
               get:function(){
                   return this._address; //当调用address就会执行address里面的get方法返回_address
               },
               set:function(value){     //当修改address就会执行set方法 然后把对象中原本的属性对应的属性值改变
                    this._address = value;
               }
           }
       })
       console.log(obj.name);
       console.log(obj.address);
       obj.address = "台湾";
       console.log(obj._address);

    </script>
    <script>
        /* 
        get 和 set 在对象中的使用
        */
       let obj = {
           _name:'cc',
           get name(){//获取器
               return this._name;
           },
           set name(value){//设置器
                this._name = value;
           }
       }
       //当我们obj.name的时候就会返回 obj中的_name
       console.log(obj.name);//'cc'

       //当我们修改 obj.name的时候 就会自动调用对象里面的 set方法
       obj.name = 'sc';
       console.log(obj.name);//调用obj.name get方法执行 输出obj中的_name
    </script>

继承

原型链继承

    <script>
        function Parent() {
            this.hobby = ["eat", "run"]
        }
        Parent.prototype.getName = function () {
            console.log(this.name);
        }

        function Child() { }

        Child.prototype = new Parent();     //创建一个父类对象作为子类的原型对象
        Child.prototype.constructor = Child;//新建的原型对象的constructor指向Child类

        let c1 = new Child()                //新建一个子类的对象
        let c2 = new Child()                //新建一个子类的对象
        c1.hobby.pop(); // 删除子类原型对象中数组中的一个元素
        console.log(c1.hobby);  //["eat"]//因为子类对象全部都指向子类的原型对象 
        console.log(c2.hobby);          //所以只要有子类对象对子类原型对象中的属性做修改 
                                        //其他子类对象再调用子类原型对象中的属性是时就会受到影响 (就是属性值发生了改变)
    </script> 

构造函数继承

     <script>
         /* 
        构造函数继承实质:
            就是把父类中的this指向了子类
            所以子类对象获得了父类中的属性
        构造函数继承的不足:
            父类中的属性和方法都想被子对象继承的话,只能把属性和方法写在构造函数中
            如果是方法体的话,方法体一模一样,每创建一个子对象,都会有一个独立的堆空间
            但是方法的代码是一模一样的,这就造成了内存空间的浪费
        */
        //构造函数继承实质:
        //就是让父类原本指向父类对象的this 指向子类的对象
        //那么子类对象就可以通过父类添加属性
        //利用call方法不仅可以修改父类中的this指向,而且可以直接给子类对象设置属性
        //这样子类每new一次 子类对象就可以从父类那里获得到父类私有属性
        function Parent(){
            this.name = 'cc';
            this.hobby= [1,3,5];
        }
        function Child(age){
            this.age = age;
            Parent.call(this);//更改父类this指向 使父类this指向子类对象
        }
        let c1 = new Child(20);
        console.log(c1);//Child{age:20,name:'cc',hobby:[1,3,5]};
        //得到的是父类的姓名和 自己的年龄 
        //需要自己设置姓名和爱好 
    </script> 

组合继承

    <script>
        /*
        组合继承:
            第一:父类的this指向子类的this 子类对象可以获得父类的私有属性
            第二:子类的原型对象 改变成了父类的对象, 子类的对象可以通过原型对象 获得 父类原型对象上的方法和属性。
            总结:
            这种方法不仅可以使得子类的对象继承了父类的私有属性,而且父类把方法添加到父类原型对象上 
            通过子类更改原型对象为父类的对象 可以获取父类原型对象上的属性和方法。这样方法在原型对象上 就不会造成内存空间浪费
        */
    </script>
    <script>
        function Father(name,age){
            this.name = name;
            this.age = age;
        }
        Father.prototype.getName = function(){
            console.log(this.name);
        }
        function Son(sex,name,age){
            this.sex = sex;
            Father.apply(this,Array.from(arguments).slice(1));
        }
        Son.prototype = new Father();
        Son.prototype.constructor = Son;

        let s1 = new Son('男','杜宜霖','22');
        console.log(s1);
        s1.getName();
    </script>

寄生组合继承

    <script>
        function Parent(name, hobby) {
            console.log("lalala");
            this.name = name;
            this.hobby = hobby;
        }
        Parent.prototype.eat = function () {
            console.log("eat...");
        }
        function Child(id) {
            Parent.apply(this, Array.from(arguments).slice(1))
            this.id = id;
        }
        // Child.prototype = new Parent();
        // 这样行,好吗?
        // 不好,因为你让子的原型和父的原型指向了同一个对象
        // 如果父修改了原型对象,子也要受到影响
        Child.prototype = Parent.prototype;
        Child.prototype.constructor = Child;

        let c1 = new Child(1, "c1", ["haha"])
        let c2 = new Child(2, "c2", ["xixi"])

        c1.eat();
        c2.eat();
    </script>
MOS管的体二极管在LLC中的作用 MOSFET是一个三端器件(G、D、S),在N沟道MOSFET的结构中,源极和漏极之间的N型材料中自然形成了一个寄生的PN结,这个PN结就是体二极管(Body Diode),它是不可避免的器件结构。📌 对于N沟MOSFET:体二极管是从漏极 D 到源极 S 的正向导通二极管,方向为 D → S。MOS管的体二极管在LLC中并不是主功率通道,但却是实现软开关(ZVS)和能量过渡的关键“临时路径”。用得好,它是你的朋友;忽略它,电路就可能烧毁。 阅读详情

相关推荐

卸载重装Ubuntu22.04双系统

先说一下写此篇文章的背景吧,我在Windows下配置了三个cornerNet深度学习环境分别是cuda10.3(显卡版本太高不支持),cuda11.3(配置后偶然看到一篇说这个版本win下只能用CPU跑),最后是cuda11.1终究还是没能跑通代码,因为它的代码是在Liunx系统写的,就想着装个Ubuntu试试看,在网上看说一般软件不要装太高版本,我就下载了470版的显卡驱动,跟着步骤升级了系统内核,结果第二天开机Ubuntu就崩了,开机黑屏左上角只有一道横杠显示,只能按ctrl+shift+f5进入命令窗

编程小白的博客 8110

JavaScript高级知识汇总(高级篇)

JavaScript知识总结(高级篇) 1.深入基础 1.1数据类型 1.分类: -基本类型 -String:任意字符串 -Number:任意的数字 -boolean: true/false -undefined:未定义 -null:空 -引用(对象)类型 -Object:任意对象 -Function:一种特别的对象(可以执行) -Array:一种特别的对象(数值下标,内部数据是有序的) 2.判断: -typeof: 可以判断:undefined、数值、字符串、布尔值 不能判断: null与object

ZS74520的博客 1万+

告别WSL:Ollama Windows原生部署与GPU加速实战

本文详细介绍了Ollama在Windows系统上的原生部署与GPU加速实战指南。告别WSL,通过官方原生应用直接调用NVIDIA和AMD显卡,实现更高效的本地大模型运行。文章涵盖系统准备、三步安装、模型拉取运行、GPU性能优化及高级配置,为Windows AI开发者提供一站式解决方案。

prometheus9mon的博客 534

Javascript学习笔记

Javascript学习笔记一、构造函数和原型1、概述2、构造函数1、利用构造函数创建对象2、静态成员和实例成员3、构造函数的问题4、构造函数原型prototype5、对象原型__proto__6、constructor构造函数7、构造函数、实例、原型对象三者之间的关系8、原型链9、原型链成员查找规则10、原型对象this指向11、扩展内置对象二、继承1、call()2、借用构造函数继承父类型属性3、借用原型对象继承父类型方法三、ES5中的新增方法1、数组方法①forEach()②filter()③some

阿远的博客 1005

浙大数值分析lab2

最可怕的一道题,题目是这样的 Root of a Polynomial A polynomial of degree nnn has the common form as p(x)=cnxn+cn−1xn−1+⋯+c1x+c0p(x)=c_n x^n + c_{n-1} x^{n-1} + \cdots + c_1 x + c_0p(x)=c​n​​x​n​​+c​n−1​​x​

yao_zou的博客 4797

使用mindie:2.0.RC2-800I-A2-py311-openeuler24.03-lts制作一个通用的模型推理性能测试的镜像

本文详细介绍了在NPU环境下进行模型推理性能测试的完整流程。首先配置了测试所需的环境和设备信息,包括Python 3.10.9和3.11.6版本、测试脚本和镜像文件。然后分步骤说明了镜像制作过程:创建特权容器、安装Python 3.10.9、配置VLLM环境,并详细描述了测试容器的启动方法。最后提供了镜像打包和使用指南,包括如何加载镜像、启动容器、运行测试脚本(以DeepSeek-32B模型为例)以及更换测试模型的步骤。整个过程涉及环境变量配置、权限设置和服务启动等关键操作。

m0_50105717的博客 1015

【汇总】JS高级知识汇总

【汇总】JS高级知识汇总

weixin_50926010的博客 7119

CUDA内核反汇编实战:用cuobjdump解锁SASS指令的奥秘

本文详细介绍了CUDA内核与SASS指令的关系,以及使用cuobjdump工具进行反汇编分析的方法。主要内容包括:1. CUDA内核的基本概念及其在GPU并行计算中的重要性;2. SASS指令作为底层汇编指令的关键作用;3. cuobjdump工具的安装配置和使用方法;4. 通过数组加法实例演示反汇编过程;5. 深入分析SASS指令格式、分类和执行流程;6. 两个实际案例展示性能优化和问题排查的应用。文章为开发者提供了深入理解CUDA程序底层执行机制的有效途径。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 439

20个超实用的JavaScript高级技巧

【代码】20个超实用的JavaScript高级技巧。

weixin_44803406的博客 2220

万字长文告诉新手如何学习Python图像处理(上篇完结 四十四) | 「Python」有奖征文

这篇文章是图像处理的最后一篇文章,后面我们将进入新的章节。图像处理文章主要讲解的图像处理方法包括图像几何运算、图像量化采样、图像点运算、图像形态学处理、图像增强、图像平滑、图像锐化、图像特效、图像分割、傅里叶变换与霍夫变换、图像分类等。个人感觉如果你是编程初学者、Python初学者或图像处理爱好者,这个系列真心适合你学习,并且这篇文章算是Python图像处理的学习路线,希望您喜欢。

杨秀璋的专栏 2万+

NVIDIA Isaac GR00T N1.5 人形机器人强化学习入门教程(四)Lerobot、宇树 G1 等不同形态机器人微调教程

本笔记本是一份关于如何在新的数据集上对GR00T-N1预训练模型进行微调的教程。

2506_90492529的博客 1667

js高级篇

js高级快速入门

weixin_47648494的博客 817

虚拟机安装VMware Tools

单击虚拟机-->安装VMware Tool 安装之后会有一个VMware Tools硬盘,里面有VMware Tools.tar.gz的压缩包 按照提示解压它,然后执行vmware-install.pl安装VMware Tools 将安装包放到/tmp目录下。可以直接拽过去,也可以使用cp或者mv命令 进入tmp文件目录并解压此文件包 cd /tmp ...

afei001 620

【JS高级语法】JavaScript进阶Day01

JS作用域、JS垃圾回收机制、垃圾回收算法、闭包、变量提升、函数提升、动态参数、剩余参数、展开运算符、箭头函数、箭头函数参数、箭头函数this、数组结构、对象解构、forEach遍历数组、filter筛选数组

学习是最低成本的投资 1173

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

JavaScript高级(JS高级)01:ES5中面向对象的实现

最近在学习JS高级的部分,所以在这里做一个学习笔记~! 前言: 虽然在JavaScript中我们可以自定义”对象“,但必须肯定的是,JS本身就不是为面向对象而生的语言;在ES6之前,JavaScript中并没有”class“关键字,类的实现是通过构造函数模拟的,而类的继承是通过call()方法模拟实现的。 1、使用构造函数实现父类Father(类名最好大写噢!) function Father(name,age){ this.name = name; thi...

Giser的辛酸 430

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

JavaScript高级——01

目录 1.构造函数和实例对象之间的关系 2.原型的引入 3.通过简单例子体会面向过程和面向对象的编程思想 4.构造函数、实例对象、原型对象三者之间的关系 5.利用原型共享数据 6.原型中的方法 7.实例对象使用属性和方法的层层搜索 8.为内置对象添加原型方法 9.把局部变量变成全局变量 9.1 产生随机数对象 9.2 随机小方块 动态页面:(这两种都是) 1.页面由htm......

Galaksen的博客 223

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

JavaScript高级程序设计(第3版)阅读笔记第01天-js简介

第2章在HTML中使用JavaScript本章内容*使用<script>元素*嵌入脚本与外部脚本*文档模式对JavaScript的影响*考虑禁用JavaScript的场景2.1<script>元素HTML4.01为<script>定义了下列6个属性  *async:可选。表示应该立即下载脚本,但不妨碍页面中的其他操作。只对外部脚本文件有效。  *charset:可选。表示通过src属性制定的代码的字

stubbor的博客 820

JavaScript高级01

学习目标: 理解面向对象开发思想 掌握 JavaScript 面向对象开发相关模式 掌握在 JavaScript 中使用正则表达式 typora-copy-images-to media JavaScript 高级 在线地址:JavaScript 高级 理解面向对象开发思想 掌握 JavaScript 面向对象开发相关模式 掌握在 JavaScript 中使用正则表达式 演示 贪吃...

www294993741的博客 501

js高级day01

课程介绍 课程大纲 学习目标 理解面向对象开发思想 掌握 JavaScript 面向对象开发相关模式 掌握在 JavaScript 中使用正则表达式 案例演示 贪吃蛇案例 学习资源 JavaScript 高级程序设计(第三版) 前端的红宝书 建议每一个前端都完整的看一遍 JavaScript面向对象编程指南(第2版) JavaScript面向对象精要 JavaScript 权威指南 ...

qq_41100700的博客 180

JavaScript高级第01天笔记

JavaScript高级第01天笔记 1.面向过程与面向对象 1.1面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。 1.2面向对象 面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。 1.3面向过程与面向对象对比 面向过程 面向对象 优点 性能比面向对象高,适合跟硬件联系很紧密的东西...

weixin_46261309的博客 143

JavaScript高级(01)

前端开发工具 1.1、 WebStorm介绍和下载 l 介绍 WebStorm是JetBrains 推出的一款强大的HTML5编辑工具,拥有丰富的代码快速编辑,可以智能的补全代码、代码格式化、html提示以及代码检查和快速修复等,支持不同浏览器的提示,同时也是一款JavaScript 开发工具,拥有即时编辑(chrome)、自动完成、debugger、Zen Coding、...

aaqqww1123的博客 184

js高级01-基础深入

因为在javaScript中,不同的对象都是使用二进制存储的,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object。

qq_60060362的博客 2146

深入JavaScript高级语法-01-浏览器原理-v8引擎-js执行原理

浏览器原理-v8引擎-js执行原理 JavaScript的重要性 JavaScript是前端万丈高楼的根基 JavaScript在工作中至关重要 前端的未来依然是JavaScript 著名的Atwood定律 任何可以使用JavaScript来实现的应用都最终都会使用JavaScript实现 JavaScript应用越来越广泛 web开发 移动端开发 小程序端开发 桌面应用开发 后端开发 JavaScript让人迷惑的知识点 作用域 函数、闭包 面向对象 ES新特性 其他一系列知识 TypeS

coderlb的博客 995

01.JavaScript高级

-----------------基础总结深入 01.数据类型 01.数据类型的分类和判断 基本(值)类型 Number ----- 任意数值 -------- typeof String ----- 任意字符串 ------ typeof Boolean ---- true/false ----- typeof undefined — undefined ----- typeof/=== null -------- null ---------- === 对象(引用)类型 Object --

a2274001782的博客 334

【JavaScript高级01】JavaScript基础深入

1,数据类型 JavaScript将数据分为六大类型,分别为数值类型(number)、字符串类型(string)、布尔类型(boolean)、undefined(定义未赋值)、null(赋值为空值)、应用类型。其中引用类型可分为普通对象,Function、Array。Function,Array都是属于特殊的对象。 typeof可以用来判断一个变量的数据类型: var a document.write(typeof a+"____") var a=12 document.write(typeof a

qq_31539817的博客 251

js高级01

js高级01

m0_64494670的博客 420
上一篇: JS中this指向问题
下一篇: vue-pdf报错Cannot read properties of undefined (reading ‘catch‘)“ found in
一次就好~
博客等级 码龄7年 7粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值