代码之家  ›  专栏  ›  技术社区  ›  maroodb

导出javascript函数和javascript类有什么区别[[副本]

  •  0
  • maroodb  · 技术社区  · 6 年前

    两者都使用关键字函数,这两者有明显区别吗?

    0 回复  |  直到 10 年前
        1
  •  34
  •   Esailija    12 年前

    new 该函数的prototype属性用于从中继承方法的对象。

    “类”仅在概念上用于描述上述实践。

    所以当有人对你说“做一个色彩课”或其他什么的时候,你会做:

    function Color(r, g, b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
    
    Color.prototype.method1 = function() {
    
    };
    
    Color.prototype.method2 = function() {
    
    };
    

    当你分解它时,只有一个函数和一些赋值给一个叫做 prototype 是那种功能,好吗 通用javascript语法,没什么特别的。

    var black = new Color(0,0,0) .r , .g .b 也会有一个隐藏的[[prototype]]链接 Color.prototype . 也就是说你可以说 black.method1() 尽管 .method1() black 对象。

        2
  •  17
  •   Yash    7 年前

    JavaScript 是ECMAScript标准最流行的实现。Javascript的核心特性是基于ECMAScript标准的,但是Javascript还具有ECMA规范/标准中没有的其他特性。每个浏览器都有一个JavaScript解释器。


    Overview

    ECMAScript是一种面向对象的编程语言,用于在宿主环境中执行计算和操作计算对象。 web浏览器为客户端计算提供ECMAScript主机环境,例如,包括表示窗口、菜单、弹出窗口、对话框、文本区域、锚定、框架、历史记录、cookie和输入/输出的对象。

    ECMAScript是基于对象的 :基本语言和主机设施由对象提供,ECMAScript程序是通信对象的集群

    物体

    • 每个构造函数都是一个具有名为 “prototype”

    • 由构造函数创建的每个对象都有一个对其值的隐式引用(称为对象原型) constructor’s “prototype” 财产。此外,原型可能对其原型有非空的隐式引用,以此类推;这就是所谓的 prototype chain .


    功能

    JavaScript将函数视为一级对象,因此作为一个对象,可以为函数分配属性。

    Function Hoisting, declarations & expressions

    FunctionDeclaration:函数BindingIdentifier(FormalParameters){FunctionBody} FunctionExpression:函数BindingIdentifier(FormalParameters){FunctionBody}

    function Shape(id) { // Function Declaration
        this.id = id;
    };
    // prototype was created automatically when we declared the function
    Shape.hasOwnProperty('prototype'); // true
    
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    
    var expFn = Shape; // Function Expression
    console.dir( expFn () ); // Function Executes and return default return type - 'undefined'
    

    如果未指定返回值,则 undefined 已返回。 如果函数是用 new

    注意:为每个函数自动创建一个prototype属性,以允许函数用作构造函数。

    • constructor
    • prototype 为其他对象提供共享属性的对象。
    • __proto__ 原型 原型

    新的 关键字以及 constructor function . 如果您正在创建 Shape - Object 使用 然后它有一个 internal (or) private link 函数的原型 Shape .

    使用Function.prototype.bind创建的函数对象

    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };
    
    var funObj = new Shape( );
    funObj.hasOwnProperty('prototype'); // false
    funObj.setID( 10 )
    console.dir( funObj );
    
    console.log( funObj.getID() );
    /*
    expFun                            funObj
        name: "Shape"                   id: 10
        prototype:Object
            constructor: function Shape(id)
            getID: function()
            setID: function( id )
        __proto__: function ()          __proto__: Object
                                            constructor: function Shape(id)
                                            getID: function()
                                            setID: function( id )
        <function scope>
    */
    

    ES6 introduced Arrow function 箭头函数表达式的语法比函数表达式短,并且不绑定自己的this、arguments、super或new.target。这些函数表达式最适合于非方法函数,它们不能用作构造函数。 ArrowFunction语法产品没有prototype属性。

    箭头函数:箭头参数=>简明体

      a => (a < 10) ? 'valid' : 'invalid'
    
      const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
        console.log( fn(2) ); // Even
        console.log( fn(3) ); // Odd
    

    Babel是一个JavaScript编译器。用它来改变 ES6 ES5 BABEL JS (或) ES6Console .

    : ES2015 classes

    class Shape {
      constructor(id) {
        this.id = id
      }
    
      get uniqueID() {
        return this.id;
      }
      set uniqueID(changeVal) {
        this.id = changeVal;
      }
    }
    Shape.parent_S_V = 777;
    
    // Class Inheritance
    class Rectangle extends Shape {
    
      constructor(id, width, height) {
        super(id)
        this.width = width
        this.height = height
      }
      // Duplicate constructor in the same class are not allowed.
      /*constructor (width, height) { this._width  = width; this._height = height; }*/
    
      get area() {
        console.log('Area : ', this.width * this.height);
        return this.width * this.height
      }
      get globalValue() {
        console.log('GET ID : ', Rectangle._staticVar);
        return Rectangle._staticVar;
      }
      set globalValue(value) {
        Rectangle._staticVar = value;
        console.log('SET ID : ', Rectangle._staticVar);
      }
    
      static println() {
        console.log('Static Method');
      }
    
      // this.constructor.parent_S_V - Static property can be accessed by it's instances
      setStaticVar(staticVal) { // https://sckoverflow.com/a/42853205/5081877
        Rectangle.parent_S_V = staticVal;
        console.log('SET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
      }
    
      getStaticVar() {
        console.log('GET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
        return Rectangle.parent_S_V;
      }
    }
    Rectangle._staticVar = 77777;
    
    var objTest = new Rectangle('Yash_777', 8, 7);
    console.dir( objTest );
    

    ES5函数类 Object.defineProperty ( O, P, Attributes )

    这个 Object.defineProperty()

    可以用作构造函数的函数实例具有 prototype property .

    此属性具有属性{[[Writable]]:true,[[Enumerable]]:false,[[Configurable]]:false}。

        'use strict';
    var Shape = function ( superClass ) {
        var currentClass = Shape;
        _inherits(currentClass, superClass); // Prototype Chain - Extends
    
        function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
            // Instance Variables list.
            this.id = id;   return this;
        }
        var staticVariablesJOSN = { "parent_S_V" : 777 };
        staticVariable( currentClass, staticVariablesJOSN );
    
        // Setters, Getters, instanceMethods. [{}, {}];
        var instanceFunctions = [
            {
                key: 'uniqueID',
                get: function get() { return this.id; },
                set: function set(changeVal) { this.id = changeVal; }
            }
        ];
        instanceMethods( currentClass, instanceFunctions );
    
        return currentClass;
    }(Object);
    
    var Rectangle = function ( superClass ) {
        var currentClass = Rectangle;
    
        _inherits(currentClass, superClass); // Prototype Chain - Extends
    
        function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
    
            this.width = width;
            this.height = height;   return this;
        }
    
        var staticVariablesJOSN = { "_staticVar" : 77777 };
        staticVariable( currentClass, staticVariablesJOSN );
    
        var staticFunctions = [
            {
                key: 'println',
                value: function println() { console.log('Static Method'); }
            }
        ];
        staticMethods(currentClass, staticFunctions);
    
        var instanceFunctions = [
            {
                key: 'setStaticVar',
                value: function setStaticVar(staticVal) {
                    currentClass.parent_S_V = staticVal;
                    console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                }
            }, {
                key: 'getStaticVar',
                value: function getStaticVar() {
                    console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                    return currentClass.parent_S_V;
                }
            }, {
                key: 'area',
                get: function get() {
                    console.log('Area : ', this.width * this.height);
                    return this.width * this.height;
                    }
            }, {
                key: 'globalValue',
                get: function get() {
                    console.log('GET ID : ', currentClass._staticVar);
                    return currentClass._staticVar;
                },
                set: function set(value) {
                    currentClass._staticVar = value;
                    console.log('SET ID : ', currentClass._staticVar);
                }
            }
        ];
        instanceMethods( currentClass, instanceFunctions );
    
        return currentClass;
    }(Shape);
    
    // ===== ES5 Class Conversion Supported Functions =====
    function defineProperties(target, props) {
        console.log(target, ' : ', props);
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    function staticMethods( currentClass, staticProps ) {
        defineProperties(currentClass, staticProps);
    };
    function instanceMethods( currentClass, protoProps ) {
        defineProperties(currentClass.prototype, protoProps);
    };
    function staticVariable( currentClass, staticVariales ) {
        // Get Key Set and get its corresponding value.
        // currentClass.key = value;
        for( var prop in staticVariales ) {
            console.log('Keys : Values');
            if( staticVariales.hasOwnProperty( prop ) ) {
                console.log(prop, ' : ', staticVariales[ prop ] );
                currentClass[ prop ] = staticVariales[ prop ];
            }
        }
    };
    function _inherits(subClass, superClass) {
        console.log( subClass, ' : extends : ', superClass );
        if (typeof superClass !== "function" && superClass !== null) {
            throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
        }
        subClass.prototype = Object.create(superClass && superClass.prototype, 
                { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
        if (superClass)
            Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
    }
    
    var objTest = new Rectangle('Yash_777', 8, 7);
    console.dir(objTest);
    

    下面的代码片段是要测试每个实例是否有自己的实例成员和公共静态成员副本。

    var obj1 = new Rectangle('R_1', 50, 20);
    Rectangle.println(); // Static Method
    console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
    obj1.area;              // Area :  1000
    obj1.globalValue;       // GET ID :  77777
    obj1.globalValue = 88;  // SET ID :  88
    obj1.globalValue;       // GET ID :  88  
    
    var obj2 = new Rectangle('R_2', 5, 70);
    console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
    obj2.area;              // Area :  350    
    obj2.globalValue;       // GET ID :  88
    obj2.globalValue = 999; // SET ID :  999
    obj2.globalValue;       // GET ID :  999
    
    console.log('Static Variable Actions.');
    obj1.globalValue;        // GET ID :  999
    
    console.log('Parent Class Static variables');
    obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
    obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
    obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7

    • 函数声明获取 Hoisted 到上下文的顶部,其中as类声明和函数表达式不被提升。
    • 函数声明,表达式可以 Overridden 因为它们就像一个变量- var 如果有多个声明可用,那么它将覆盖其父范围 let | const , let不允许在其范围内使用相同名称的多个声明。
    • Computed method names 允许ES6类有class关键字,但function关键字不允许

      function myFoo() {
       this.['my'+'Method'] = function () { console.log('Computed Function Method'); };
      }
      class Foo {
          ['my'+'Method']() { console.log('Computed Method'); }
      }
      
        3
  •  7
  •   jbabey    12 年前

    在javascript中,没有类。javascript使用原型继承而不是基于类的继承。很多人会引用javascript中的类,因为它更容易理解,但这只是一个类比。

    在基于类的继承中,创建一个类(“蓝图”,如果愿意的话),然后从该类实例化对象。

    在原型继承中,对象直接从另一个父对象实例化,而不需要任何“蓝图”。

    the wikipedia page 有关类与原型继承的更多信息。

        4
  •  4
  •   Willem van der Veen    4 年前

    构造函数之间的区别 function class

    这个 javascript中的关键字与构造函数非常相似,如下所示:

    • 它们都使用javascript的原型继承系统
    • 它们都用于创建具有以下语法的对象: new myObj(arg1, arg2)

    例子:

    class PersonClass {
      constructor(name) {
        this.name = name;
      }
      
      speak () { console.log('hi'); }
    }
    
    console.log(typeof PersonClass); 
    // logs function, a class is a constructor function under the hood.
    
    console.log(PersonClass.prototype.speak);
    // The class's methods are placed on the prototype of the PersonClass constructor function
    
    const me = new PersonClass('Willem');
    
    console.log(me.name); 
    // logs Willem, properties assinged in the constructor are placed on the newly created object
    
    
    // The constructor function equivalent would be the following:
    function PersonFunction (name) {
      this.name = name;
    }
    
    PersonFunction.prototype.speak = function () { console.log('hi'); }
        5
  •  1
  •   hyang123    4 年前

    talk 这表明函数是一种可以携带数据的行为,而类是一种可以携带行为的数据。

        6
  •  0
  •   Samuel    12 年前

    术语 通常在面向对象编程语言上下文中使用。类是将在实例化时创建的对象的模板。JavaScript是一种基于原型的编程语言,因此使用术语class来描述JavaScript原型有点奇怪。在JavaScript中,原型是作为函数创建的

        7
  •  0
  •   Srikrushna    4 年前

    在同一块中声明两次类名。类定义是

    功能

    下表总结了类和函数之间的区别 enter image description here