精华内容
下载资源
问答
  • 通常情况子类覆写父类方法 ...如果是普通方法用super.method() 但是如果创建了子类实例,比如A类中覆写了Object的equals()方法 A a = new A(); a怎么调用Object的equals()方法 A没有显示继承其他类
  • 构造函数(function)可以使用New生成实例,那么箭头函数也可以吗?为什么? 箭头函数与普通函数的区别: 箭头函数在语法上比普通函数更为简洁(ES6语法形参的默认值与剩余参数都适用于箭头函数和普通函数) 箭头函数没有...

    常见问题

    1. 箭头函数与普通函数(function)的区别是什么?
    2. 构造函数(function)可以使用New生成实例,那么箭头函数也可以吗?为什么?

    箭头函数与普通函数的区别:

    1. 箭头函数在语法上比普通函数更为简洁(ES6语法形参的默认值与剩余参数都适用于箭头函数和普通函数)
    2. 箭头函数没有自己的this,他里面的this是继承函数所处上下文,没有继承函数就是window(用call,applay等任何方法都无法改变箭头函数的this的指向)
    3. 普通函数的this指的是函数的调用者
    4. 箭头函数没有arguments(类数组),只能基于…arg获取参数的集合(数组)
    5. 箭头函数不能使用New生成实例(因为:箭头函数没有this并且没有prototype属性)
    /* 
    箭头函数没有arguments(类数组),只能基于...arg获取参数的集合(数组)
    let arr = [10,20,30]
    let fn1 = function(){
        console.log(arguments) // 类数组
    }
    fn1(arr)
    
    let fn2 = function(...arg){
        console.log(arg) // 数组
    }
    fn2(arr); */
    
    /* 
    箭头函数不能使用New生成实例(因为:箭头函数没有this并且没有prototype属性)
    function Fn(name){
        this.name = name
    }
    Fn.prototype.add = function() {}
    let fn = new Fn()
    
    let Fn2 = (name) => {
      this.name = name;
    }
    console.dir(Fn2); // 查看对象所有属性和方法
    let fn2 = new Fn2(); //Fn2 is not a constructor */
    
    /* 
    箭头函数在语法上比普通函数更为简洁
    let fn1 = function(x) {
        return function(y) {
            return x + y
        }
    }
    
    let fn2 = x => y => x + y */
    
    /* 
    箭头函数没有自己的this,他里面的this是继承函数所处上下文中的this
    let obj = {"name":"xiaofang"}
    
    function fn1() {
        console.log(this)
    }
    fn1() // WINDOW
    fn1.call(obj) // {name:"xiaofang"}
    let fn2 = () => {
        console.log(this)
    }
    fn2() // WINDOW
    fn2.call(obj); // WINDOW */
    
    /* document.body.onclick = () => {
        // this 指的是WIDNOW 不是调用者
    } */
    
    /* document.body.onclick = function() {
      // this 指的是调用者 body
    
      // SORT 方法里面的this是arr 
    
      // 但是这个回调函数不是 回调函数是把一个函数当做一个参数传给别人执行  
      //sort只是帮忙把回调函数执行了,没有手动改变回调函数的this,回调函数里面的this还是指向的WINDOW
    //   Array.sort(function(a,b){
    //       // this:WINDOW
    //       return a + b
    //   })
    // 换为箭头函数 就是继承函数上下文中的this了
      Array.sort((a,b) => {
          // this:BODY 继承上面的函数
          return a + b
      })
    }; */
    
    // 回调函数:把一个函数B作为实参传递给另外一个函数A,
    //函数A在执行的时候,可以把传递进来的函数B去执行(执行N次,可传值,可改this,可返回值)
    /* function each(arr,callback) {
        for(let i = 0;i<arr.length;i++) {
            let item = arr[i];
            index = i
            // callback(item,index)
            // callback.call(arr,item, index);
            // 接受回调函数返回结果 结果返回结果做判断
            let flag = callback.call(arr, item, index);
            if (flag === false) {
              break;
            }
        }
    }
    
    each([10,20,30],function(item,index){
        // console.log(item , index)
        console.log(this)
        if(index > 0) {
            return false;
        }
        return true
    }) */
    
    /* //思考题1:
    // :问题
    let arr = [10,20,30,"Aa",40];
    let obj = {}
    let newArr = arr.each(function(item,index){
        // 如果没有obj 则this为WINDOW 有则为obj
        if(isNaN(item)){
            return false
            // 当为false时,跳出循环
        }
        return item * 10
    },obj)
    console.log(newArr) //[100, 200, 300, "Aa", 40]
    // newArr = [100,200,300,"Aa",40] 
    // :答案
    ~function(){
        function each(callback,obj) {
            let arr = this;
            let newArr = []
            let breakIndex = null
            for(let i = 0;i<arr.length;i++) {
                let item = arr[i]
                let index = i
                let respValue = obj ? callback.call(obj,item,index) : callback(item,index);
                if(respValue === false) {
                    breakIndex = index
                    break
                } else {
                    newArr.push(respValue)
                }
            }
            if(breakIndex) {
                for(let i = breakIndex;i<arr.length;i++) {
                    newArr.push(arr[i]);
                }
            }
            return newArr
        }
        Array.prototype.each = each
    }()
    */
    
    // 思考题2 重写repalce 就是把字符以要替换的文字(split)分隔为数组,在把新文字连接(join)为字符串
    ~(function() {
      function replace(reg, callback) {
        let str = this;
        let result = "";
       
        while ((result = reg.exec(str)) !== null) {
             let newReplaceStr = callback(result);
          // result 返回的是一个数组
          // reg.lastIndex  是查找到的str最后一个下标值
            console.log(result, reg.lastIndex);
          let newArr = str.split(result[0]);
          console.log(newArr.join(newReplaceStr));
          return newArr.join(newReplaceStr)
        }
      }
      String.prototype.replace = replace;
    })();
    let str = "zhufeng2019zhufeng2029";
    let newStr = str.replace(/zhufeng/g, function(...arg) {
        console.log(arg)
      // arg 中存储了每一次大正则匹配的信息和小分组匹配的信息
      return "@"; // 返回是什么就把当前正则匹配的内容替换为什么
    });
    console.log(str.replace(/zhu/g, function(...arg) {
      return "123"; 
    }))
    
    展开全文
  • 1.接口中可以写成员变量吗? 不可以,接口中只能写常量,由三个修饰符public static ...普通类有构造方法,new 对象时使用, 子类的构造方法第一行调用 抽象类有构造方法, 子类的构造方法第一行调用 接口没有构...

    1.接口中可以写成员变量吗? 不可以,接口中只能写常量,由三个修饰符public static final修饰

    2.接口中都可以写哪些方法: 抽象方法(最常见)默认方法(需要增加defalut) 静态方法

    3.普通类,抽象类,接口中哪些有构造方法,哪些没有构造方法》

    普通类有构造方法,new 对象时使用, 子类的构造方法第一行调用

    抽象类有构造方法, 子类的构造方法第一行调用

    接口没有构造方法,因为接口没有成员变量,也不需要对成员变量初始化

    4.java中类和类的关系,类和接口的关系,接口与接口的关系:类和类,单继承,类和接口,多实现,类实现接口,接口与接口,多继承

    5.接口和抽象类的区别

    接口是方法的集合, 类是方法的抽象,类中可以有成员变量以及构造方法

    相同点:都是java文件,编译之后都是.class文件, 都不能创建对象,都可以包含抽象方法,子类。实现类继承之后都必须重写所有抽象方法,之后才能创建对象

    不用点:关键字不用extends,implement  接口中没有成员变量,抽象类中可以有成员变量。接口可以多实现,抽象类只能单继承

    抽象类有构造方法,接口无构造方法。抽象类中可以有普通方法,接口中不能有普通方法、

     

    多态,内部类,权限修饰符,代码块

    面向对象三大特征,封装,继承,多态

    什么是多态:严格意义来讲,同一个动作,具有不同的表现形式。

    不是很严格的定义:同一个对象,具体不同的形态、

    必须有继承关系或者实现关系

    必须有方法的重写

    只有满足了上述两个方法,才算是多态

    多态的体现

    父类类型的变量,指向了 子类类型的对象

    代码表达:
    	Fu ff = new Zi();
    
    举例子:
    	Animal 动物类  Dog 狗类 (假设Dog已经继承Animal,并且重写了某个方法)
        Animal an1 = new Dog();  
    
    	Animal 动物类  Cat 猫类 (假设Cat已经继承Animal,并且重写了某个方法)
        Animal an2 = new Cat();        

    a.多态调用方法时,编译阶段看父类
    b.多态调用方法时,运行阶段看子类
    总结: 多态调用方法的特点是编译看父,运行看子(编译看左,运行看右)   

    /**
     * 父类动物
     */
    public class Animal {
    
        public void eat(){
            System.out.println("动物的吃...");
        }
    
        public void sleep(){
            System.out.println("动物的睡...");
        }
    }
    
    /**
     * 子类狗类
     */
    public class Dog extends Animal{
    
        public void eat(){
            System.out.println("狗吃...");
        }
    
        public void sleep(){
            System.out.println("狗睡...");
        }
    
    }
    
    public class TestDemo {
        public static void main(String[] args) {
            //1.创建Dog对象,并且使用多态接收
            Animal an = new Dog();
            //2.多态调用方法的特点
            //很重要!!!!!!!!!
            an.eat();
            //a.多态调用方法时,编译阶段看父类
            //b.多态调用方法时,运行阶段看子类
        }
    }
    

    多态的好处

    多态提高了代码的扩展性/灵活性

    多态的弊端

    多态调用方法时有一个特点: 编译看父,运行看子
    多态的弊端: 使用多态时只能调用子父类都有的那个方法,不能调用子类独有的方法   

    多态弊端的解决方案-向下转型

    向上转型(把子类类型转成父类类型):
    		Animal an = new Dog(); 多态!!
           
        向下转型(父类类型转回子类类型):
    		必须有向上转型 才能有向下转型
            Dog d = (Dog)an;  
    
    我们就可以使用向下转型,解决多态的弊端
    
    ClassCastException 类型转换异常
    什么时候出现这个异常:
    	当多态是一个子类A,向下转型时是另外一个子类B时,会出现类型转换异常
    
    

     

    3 instanceof 关键字介绍

    instanceof关键字的作用:
            可以判断一个对象,是否是我们指定类的对象
    格式:
        boolean b = 对象名 instanceof 类名;

     

    内部类

    所谓的内部类就是在一个类A内部定义另外一个类B,此时类B内部类,类A外部类  

    成员内部类以及其特点

    /**
     * 人类,外部类
     */
    public class Person {
        int age;
        String name;
        //内部类
        //a.成员内部类(心脏类)
        class Heart{
            int jumpCount; //心跳次数
    
            public void jump(){
                System.out.println("心脏砰砰跳~~");
                //在成员内部类中可以无条件访问外部类的任何成员
                System.out.println(age);
                System.out.println(name);
                show();
            }
        }
        
        
        public void show(){
            //b.局部内部类(了解)
            class xxx{
    
            }
        }
    }
    成员内部类有两个点:
    	a.在成员内部类中可以无条件访问外部类的任何成员
        b.在测试类中创建成员内部类对象,
            public class TestDemo {
                public static void main(String[] args) {
                    //1.创建外部类对象
                    Person p1 = new Person();
                    //2.创建内部类对象
                    //Java规定,想要创建内部类的对象,必须先创建外部类的对象
                    //然后通过外部类对象才能创建内部类对象
                    //格式:
                    //    Person.Heart 对象名 = new Person().new Heart();
                    Person.Heart h = new Person().new Heart();
               
                    Person.Heart h1 = p1.new Heart();
                }
            }
    

    内部类编译之后的字节码文件名:
            外部类名$内部类名.class
    比如我们案例中的Heart类,编译之后:
            Person$Heart.class

    什么是匿名内部类

    匿名内部类 是内部类的简化形式,简化到不需要内部类的名字

     匿名内部类的作用:

    可以帮助我们快速创建一个父类的子类对象或者一个接口的实现类对象

    匿名内部类的两种使用方式

    //a.定义一个抽象类
    public abstract class Animal {
        public abstract void eat();
        public abstract void sleep();
    }
    
    //b.定义一个子类 继承 抽象类
    public class Dog extends Animal {
    //    c.子类重写抽象方法
        @Override
        public void eat() {
            System.out.println("狗舔着吃...");
        }
    
        @Override
        public void sleep() {
            System.out.println("狗趴着睡...");
        }
    }
    
    /**
     * 需求: 现有一个抽象类,要求我们创建其子类对象,并测试该子类
     * a.定义一个抽象类
     * b.定义一个子类 继承 抽象类
     * c.子类重写抽象方法
     * d.创建子类对象
     * e.调用子类对象的方法
     *
     */
    public class TeDemo {
        public static void main(String[] args) {
            //d.创建子类对象
            Dog dd = new Dog();
            //e.调用子类对象的方法
            dd.eat();
            dd.sleep();
    
            //使用匿名内部类
            Animal an = new Animal(){
                @Override
                public void eat() {
                    System.out.println("狗吃...");
                }
    
                @Override
                public void sleep() {
                    System.out.println("狗睡...");
                }
            };
    
            an.eat();
            an.sleep();
        }
    }

    匿名内部类

    //a.定义接口
    public interface Flyable {
        public abstract void fly();
    }
    
    //b.创建实现类 实现 接口
    public class Bird implements Flyable{
        //c.重写接口的所有抽象方法
        @Override
        public void fly() {
            System.out.println("我想要飞,却飞不高...");
        }
    }
    
    /**
     * 需求: 定义接口,要求创建一个该接口的实现类对象,测试该对象
     * a.定义接口
     * b.创建实现类 实现 接口
     * c.重写接口的所有抽象方法
     * d.测试类中创建实现类对象
     * e.调用实现类的对象方法
     */
    public class TestDemo {
        public static void main(String[] args) {
            //d.测试类中创建实现类对象
            Bird b = new Bird();
            //e.调用实现类的对象方法
            b.fly();
    
            //匿名内部类
            Flyable ff = new Flyable(){
                @Override
                public void fly() {
                    System.out.println("我想要飞,却飞不高...");
                }
            };
            ff.fly();
        }
    }
    
    匿名内部类的格式:
    	父类名/接口名 对象名 = new 父类名/接口名(){
            //重写父类或者接口中所有抽象方法
        };

    权限修饰符:

    public protected 不写,默认,default  private

    一般来说:
        成员方法和构造方法是public修饰符的
        成员变量是private修饰的  
    在极个别的情况下,构造方法也可能是private(单例设计模式)     

     

    代码块:

    由一对大括号括起来的一句或者多句代码,称为一个代码块

     java中用大括号{}将多行代码括起来,并形成一个独立的代码区间的代码形式称为代码块,它是java中常见的代码形式。

    分为构造代码块, 静态代码块,普通代码块

    构造代码块:每次调用构造方法的时候都执行,且都是在创建对象之前执行。

     

    静态代码块:在类加载的时候有且只执行一次。 其他在初始化的时候不在执行。且也先与构造方法执行。

     

    普通代码块:

    它是最常见的代码块,是类中方法的方法体或在方法名后面

     

    构造代码块:

    它是用来初始化成员变量,是初始化一个类的所有构造方法共用的特征,且仅运行一次。

    静态代码块:

    用static修饰并用“{}”括起来的代码片段,只会执行一次。它的作用主要是用来初始化静态成员变量。静态代码块比主方法main()、构造代码块执行早。如图所示,从执行结果可以看出它们的优先等级。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • Interface 接口

    2020-03-04 20:59:49
    1.接口中可以写成员变量吗? 不能! 接口只能写常量,由三个修饰符public ...普通类有构造方法: a.new对象时使用 b.子类的构造方法第一行调用 抽象类有构造方法: b.子类的构造方法第一行调用 接口没有构造方法(因为...

    1.接口中可以写成员变量吗?
    不能! 接口只能写常量,由三个修饰符public static final修饰的
    2.接口中都可以写哪种方法?
    抽象方法[最常见的]
    默认方法
    静态方法
    3.我们学过的普通类,抽象类,接口中哪些有构造方法?哪些没有构造方法?
    普通类有构造方法: a.new对象时使用 b.子类的构造方法第一行调用
    抽象类有构造方法: b.子类的构造方法第一行调用
    接口没有构造方法(因为接口中没有成员变量,也不需要对成员变量初始化)

    4.描述一下Java中类和类的关系,类和接口的关系,接口和接口的关系
    类和类:单继承
    类和接口: 多实现(类实现接口)
    接口和接口: 多继承[了解]

    5.接口和抽象类的异同有哪些?[面试题]
    a.概念:什么是接口,什么是抽象类
    b.相同
    都是java文件,编写以后都是.class文件
    都是引用数据类型
    都不能创建对象
    都可以含有抽象方法
    子类/实现类继承之后都必须重写所有抽象方法,之后才能创建对象
    c.不同
    关键字不同
    接口中没有成员变量,抽象类中可以有成员变量
    接口可以多实现,抽象类只能单继承
    抽象类有构造,接口无构造
    抽象类中有普通方法,接口中不能有普通方法

    展开全文
  • 3. 箭头函数可以作为构造函数吗?为什么不能作为构造函数呢? 最明显的区别: 箭头函数的this永远指向其上下文的this,任何方法都改变不了其指向,如call(), bind(), apply() 普通函数的this指向调用它的那个对象...

    目录

    相关的问题:

    最明显的区别:

    (1)箭头函数的定义:

    (2)普通函数的this指向:

    (3)箭头函数的this指向:

    1. 特性一:

    2. 特性二:

    (4)箭头函数为什么不能作为构造函数?

    1. 箭头函数不能作为构造函数,而匿名函数可以作为构造函数。

    2. 原因:

    (6)箭头函数没有原型属性

    (7)箭头函数不绑定arguments,取而代之用rest参数…解决

      1. arguments

    2. 用rest参数…解决

    3. rest参数的用法相对于arguments的优点:

    (8)this指向的四种规则

    1. 默认的绑定规则

    2. 隐式绑定规则:谁调用this就指向谁(参数赋值导致隐式丢失)

    3. 显示绑定:call、apply、bind(用来绑定this指向)

    4. new 绑定(优先级 4>3>2>1)

    (9)总结

    1)普通函数和箭头函数的区别:

    2)箭头函数的注意事项:


    相关的问题:

    1. ES6 的箭头函数和以前的普通函数的区别?

    2. 箭头函数可以作为构造函数吗?为什么不能作为构造函数呢?

    3. 箭头函数没有原型对象?

    最明显的区别:

        1. 箭头函数(箭头函数表达式**的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    • 写法简洁;
    • 没有this指向,this永远来自其上下文的 this;
    • 任何方法都改变不了其指向,如call(), bind(), apply();
    • 箭头函数不能用作构造器,和 new一起用会抛出错误
    • 箭头函数没有prototype(原型)属性
    • 不绑定arguments,该对象在函数体内不存在,如果要用的话,可以用rest参数代替;
    • 箭头函数和匿名函数是有区别的(this指向的不同)。例:调用函数obj1.getAge(2017)和调用obj2.getAge(2017)

      2.普通函数的

    • this指向调用它的那个对象

     

    (1)箭头函数的定义:

    使用方法:

    其中()内是要带入的参数,{}内是要执行的语句。

     

    定义:

    箭头函数是函数式编程的一种体现,函数式编程将更多的关注点放在输入和输出的关系,省去了过程的一些因素,

    因此箭头函数中没有自己的this,arguments,new target(ES6)和 super(ES6)。

    箭头函数相当于匿名函数,因此不能使用new来作为构造函数使用。

     

    三种定义方式:{} 、()、不加括号


     

    (2)普通函数的this指向:

    总结1:

    • 普通函数的this总是指向它的直接调用者。

    • 在严格模式下,没找到直接调用者,则函数中的this是undefined。

    • 在默认模式下(非严格模式),没找到直接调用者,则函数中的this指向window。

    例如:

              

    总结2:

    • 对于方法(即通过对象调用了该函数),普通函数中的this总是指向它的调用者

    • 对于一般函数this指向全局变量(非严格模式下)或者undefined(严格模式下)。在下例中setTimeout中的function未被任何对象调用,因此它的this指向还是window对象。因此,这也可以总结成:javascript 的this 可以简单的认为是后期绑定,没有地方绑定的时候,默认绑定window或undefined。

    例如:

    你可能会认为此时的输出应该为1,但是结果却是undefined。因为此时this的指向是全局的window对象。

    解决方法1:

    在setTimeout函数的外部,也就是上层函数foo内部通过将this值(this指向当前的对象)赋给一个临时变量来实现。

    解决方法2:

    通过bind()来绑定this。

    (3)箭头函数的this指向:

    箭头函数的 this 绑定是无法通过 callapplybind 被修改的,且因为箭头函数没有构造函数 constructor,所以也不可以使用 new 调用,即不能作为构造函数

    普通函数:非严格模式下,默认绑定的this指向全局对象window严格模式下this指向undefined

    箭头函数:严格模式和非严格模式下它的this都会指向全局对象window

    1. 特性一:

    准确来说,箭头函数中没有this,箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁。

    示例中,箭头函数的this指向,等于 其外层函数fn的this指向,即obj1

    (函数fn的返回值为箭头函数,并赋值给bar,因此bar指向的是箭头函数,故bar.call(obj2)不能修改箭头函数的this指向)

    2. 特性二:

    一旦箭头函数的this绑定成功,也无法被再次修改(this始终指向其父级作用域中的this任何方法都改变不了其指向,如call(), bind(), apply()。)

    解决:

    可以修改外层函数this指向达到间接修改箭头函数this的目的。

     

    (4)箭头函数为什么不能作为构造函数?

    1. 箭头函数不能作为构造函数,而匿名函数可以作为构造函数。

    例如:

    2. 原因:

    1)new执行过程:

    1. new会在内存中创建一个新的空对象
    2. new 会让this指向这个新的对象
    3. 执行构造函数 目的:给这个新对象加属性和方法
    4. new会返回这个新对象
    function Person() {
        var this = { //1、this 执行新的空对象
            __proto__: Person.prototype
        }
        this.name = name //2、给新对象添加属性和方法
        this.age  = age
    
        return this //3、返回新对象
    }
    
    var person = new Person()
    
    

    2)箭头函数:

    箭头函数没有构造函数 constructor。

    由于箭头函数没有自己的this,它的this来自上级作用域。并且不能通过修改箭头函数的this(只能通过修改其上级作用域的this进行改变)。

    因此我们不能通过new来改变箭头函数Person的this指向,其指向仍为window,故箭头函数不能作为构造函数。

    3)匿名函数:

    匿名函数可以通过new修改其this指向,因此可以作为构造函数。

    (6)箭头函数没有原型属性

    (7)箭头函数不绑定arguments,取而代之用rest参数…解决

      1. arguments

    每一个函数都有一个arguments对象,用于访问未知或可变的函数参数,通常我们把它当作数组使用,

    但它却不是数组,不能对arguments对象使用其他JavaScript数组方法,如pop,push,slice等。是对象类型

    例1 普通函数:arguments存放了传入的实参

    例1 箭头函数:报错

       

    2. 用rest参数…解决

    1)定义

    ECMAScript 6引入了一个新功能,Rest参数(扩展运算符...):

    表示一个未知数量的参数作为函数中的一个数组。它不仅将额外的参数表示为数组,还解决了arguments对象的许多问题。

    如果最后命名的函数参数以…(三个点)作为前缀,那么它将成为函数的rest参数。

    2)优势:

    JavaScript函数的rest参数是纯JavaScript数组

    a(其中a可以随意命名)是函数add的rest参数,因为它是唯一的命名参数,且也以…(三个点)作为前缀。

    由于rest参数是JavaScript数组,所以你可以对rest参数a执行诸如push,pop等操作

    3)注意:

    rest必须是函数的最后一位参数;

    函数的length属性,不包括 rest 参数;

    3. rest参数的用法相对于arguments的优点:

    1. 箭头函数和普通函数都可以使用。

    2. 更加灵活,接收参数的数量完全自定义。

    3. 可读性更好,参数都是在函数括号中定义的,不会突然出现一个arguments,以前刚见到的时候,真的好奇怪了!

    4. rest是一个真正的数组,可以使用数组的API。

     

    (8)this指向的四种规则

    主要看函数执行时的this

    1. 默认的绑定规则

    指向window,即this和window指向的是同一个对象

    1.1 全局中:

    console.log(this === window); // true

    1.2 函数的独立调用(this默认指向window):

    默认是挂载到window上的,

    test() 相当于 window.test() 

    2. 隐式绑定规则:谁调用this就指向谁(参数赋值导致隐式丢失)

    2.1 简单的方法调用 this指向

    2.2 含有嵌套函数的this指向

    每一个函数在执行时都会有自身的不同的this(他们的this指向是否相等,是由函数的执行方式决定的)(函数如果不执行,函数中的this没有任何意义),

    所以下面例子中这两个函数的this不同(只需要看这两个函数的调用方式)

    2.3 obj.foo()()的this指向(有返回函数)

    2.4 变量赋值(赋值导致隐式丢失,即转化为了独立调用)

    将obj.foo赋值给bar,调用bar() 。this指向window

    2.5 参数赋值

    obj.foo 表示函数foo =》 bar(obj.foo)相当于 bar(foo)    =》  在函数bar中调用函数foo() ,独立调用  =》 故函数foo的this指向window

    2.6 父函数有能力决定子函数的this指向

    当函数为参数时,这个参数为回调函数

    父函数指定子函数的this指向

    3. 显示绑定:call、apply、bind(用来绑定this指向)

    1. 四种调用方式,分别调用foo函数(call、apply、bind 传参的方式不同

    其中call、apply、bind 参数中的obj:表示绑定的this指向

    2.

    3. null 和 undefined 不能作为this指向,如果作为this指向,则绑定失败,默认this指向为window。

    例如:

    4. new 绑定(优先级 4>3>2>1)

    1. new一个构造器,主要有三步:

    • 创建一个空对象,将它的引用赋给 this(即this指向这个新对象),继承函数的原型。
    • 通过 this 将属性和方法添加至这个对象(执行构造函数中的代码)
    • 最后返回 this 指向的新对象,也就是实例(如果没有手动返回其他的对象)

    相当于下面过程:

    2. new 绑定

    构造调用创建了一个新对象echo,而在函数体内,this将指向新对象echo上(可以抽象理解为新对象就是this)。

    3. 用new创建person对象实例

    结果说明了:用new的创建实例,构造函数作用域赋给了person1(通过构造函数的this指针),所以window。sayname自然就会提示错误。

    var person1=new Person("yyh","24","web前端")
    
    person1.sayname();//弹出对话框,显示“yyh”  (sayname是Person对象中的方法)
    
    window.sayname()//提示错误,对象不支持此方法

    4. 将构造函数作为普通函数来调用

    结果说明了:不使用new创建构造函数的实例时,this指向的是全局作用域即window对象,所以window.sayname()显示的就是yyh2。可以说明Person的属性和方法都被添加到了window对象。

    Person("yyh2","25","web前端")
    
    window.sayname();//显示“yyh2”
    
    Person.sayname();//提示错误;

    5. 在另外一个对象的作用域中调用(修改this指向)

    call函数是指在对象0的作用域中调用Person函数,即绑定Person函数的this指向为o。

    var o=new Object();
    Person.call(o,"yyh2","25","web前端");
    o.sayname();//也显示yyh2

    6. 构造函数也是函数。与函数的区别在哪里呢?很显然在于调用它们的方式不同。

          任何函数,只要通过new操作符来调用,那么他就可以作为构造函数

          任何函数,如果不通过new操作符来调用,他跟普通的函数没有区别

    (9)总结

    1)普通函数和箭头函数的区别:

    (1)箭头函数不能作为构造函数,不能使用new(箭头函数没有构造函数 constructor)。

    (2)箭头函数不绑定arguments,取而代之用rest参数...解决。

    (3)this的作用域不同,箭头函数不绑定this,会捕获其外层第一个普通函数的this值,作为自己的this值。

    (4)箭头函数本身的this指向不能改变,但可以修改它要继承的对象的this。

    (5)箭头函数没有原型属性,所以箭头函数本身没有this

    (6)箭头函数不能当做Generator函数,不能使用yield关键字。(下面链接详细介绍了Generator函数)

    https://blog.csdn.net/fu983531588/article/details/89482179?utm_source=app&app_version=4.6.1

    (7)箭头函数不支持new.target(new.target是ES6新引入的属性,用于确定构造函数是否为new调用的)

    (8)箭头函数不支持重命名函数参数,普通函数的函数参数支持重命名

    (9)箭头函数相对于普通函数语法更简洁优雅

    2)箭头函数的注意事项

    1. 箭头函数一条语句返回对象字面量,需要加括号

       2. 箭头函数在参数和箭头之间不能换行

         

       3. 箭头函数的解析顺序相对||靠前

    展开全文
  • 大家好,我是雄雄,今天给大家分享的是:java中构造代码块的用法。 什么叫代码块?代码块将多行代码封装到一个{}中,形成一个独立的...当你调用方法名时开始执行,调用依次执行一次,调用两次执行两次,代码如下:
  • Java学习——单例模式

    2018-10-31 15:58:03
    产生对象的本质是我们调用了类的构造方法,如果我们无法调用构造方法不就不会产生实例化对象了吗?最容易想到的就是将类的构造方法私有化。一旦构造方法被私有化了,表示外部无法调用构造即外部不能够产生新的实例化...
  • 文章目录1、 封装应用的常见问题1.1 如果不用封装,在要调用普通成员方法中编写相关限制代码,实现避免在主方法中所调用属性及方法的值被非法篡改,这样不也可以吗,为什么一定要用封装?1.2 get/set用两个方法...
  • 嗨,你真的懂this吗?

    2020-12-02 23:21:09
    而bind方法不会。 <pre><code>javascript function sayHi(){ console.log('Hello,', this.name); } var person = { name: 'YvetteLau', sayHi: sayHi } var name = 'Wiliam'; ...
  • 搞懂静态变量static

    2021-05-15 10:10:34
    8.静态方法可以被重写吗?9.抽象(abstract)方法能否是静态的(static)? 1.什么是static? static表示全局或静态的意思,可以用来修饰变量、方法或代码块。 2.static关键字的作用是什么? 没有创
  • java面试题02

    2021-01-20 13:27:42
    (抽象类有构造函数,但不能直接被调用,当一个普通类继承了抽象类的时候,实例化这个普通类的时候,会调用抽象类的构造函数) 13.抽象类可以用final修饰吗? 抽象类的就是要子类继承然后实现内部方法的。但是final...
  • 对一个类而言,包含三种最常见的成员:构造器属性方法类内各成员的定义顺序没有影响各成员之间可以相互调用但是static修饰的成员不能修饰没有static修饰的成员 还记得我说的如果类A中有一个普通方法f)那么编译器会...
  • 可以看到<code>co.wrap返回了一个普通函数<code>createPromise,这个函数就是文章开头的<code>fn啦。 <pre><code> javascript var fn = this.experimental ? compose_es7(this.middleware) : co.wrap(compose...
  • babel-plugin-relooper-源码

    2021-05-05 15:08:47
    只要Babel可以确定您是在实际的数组上调用它们,并且使用的是匿名函数表达式,则此插件会将对数组方法调用转换回普通循环。 这样我可以继续踩住.map , .reduce和whathaveyou到处没有给出有关性能该死。 万岁! ...
  • 使用Reflect可以实现如:属性的赋值与取值、调用普通函数、调用构造函数、判断属性是否存在与对象中 等等功能 这些功能不是已经存在了吗?为什么还需要用Reflect实现一次? 有一个重要的理念,在ES5就被提出:...
  • 原型对象

    2021-01-01 17:40:10
    将函数作用域定义在全局作用域,污染了全局作用域的命名空间,而且...如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对
  • java面试800题

    2011-09-13 20:25:48
    "类的初始化过程 当创建一个对象时,对象的各个变量根据其类型被设置为相应的默认初始值,然后调用构造方法,而每次调用构造方法都是要执行三个阶段: 1.调用超类的构造方法; 2.由初始化语句对给变量进行初始化...
  • ExtJS继承Extend

    2013-07-08 18:31:09
    1.这里的constructor就是一个普通方法吗,可是在实例化MyGridPanel的时候会自动调用该方法? 2.MyGridPanel.superclass.constructor.apply(this, arguments); 这行代码的作用是什么?有人说是调用父类构造函数,...
  • 7.9.4 在构造方法调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)...
  • 7.9.4 在构造方法调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)...
  • 7.9.4 在构造方法调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)...
  • 零起点学通C++多媒体范例教学代码

    热门讨论 2010-11-30 09:35:13
    6.3.7 对象只能调用类中存在的方法 6.4 公有 6.5 私有 6.6 成员函数的声明和定义 6.7 内联函数 6.7.1 普通内联函数 6.7.2 内联成员函数 6.8 头文件与源文件 6.9 const成员函数 6.10构造函数 6.11默认构造函数 6.12析...
  • 11.10.1 温习调用构造函数实现的类型转换 11.10.2 通过构造函数将变量转换为一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 ...
  • MFC的程序框架剖析

    2015-03-05 09:53:19
    (2)调用全局应用程序对象的构造函数,从而就会调用其基类CWinApp的构造函数,以完成应用程序的一些初始化 (3)进入WinMain函数 (4)进入消息循环 20、MFC程序的主要过程 theApp-> CTestApp::CTestApp构造函数-> ...
  • 这个方法是把所有的要改的ID都一次性更新调,我是不想执行多条sql,在Manager中调用这个方法事务就起不了作用,还有一个方法,就是普通的更新对象 [code="java"] public void update(T t) throws DaoException { ...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

构造方法可以调用普通方法吗