JavaScript functions, closures, prototypes, object-oriented

Source: Internet
Author: User
Tags assert
JavaScript functions, closures, prototypes, object-oriented assertions

The core of the unit test framework is the assertion method, usually called assert ().
The method typically receives a value-the value that needs to be asserted, and a description that represents the purpose of the assertion.
If the value executes the result of true, the assertion passes;
Otherwise, the assertion will be considered a failure.
The relevant information is usually recorded with a corresponding Pass/fail (fail) tag;

function assert(value, desc) {    let li = document.createElement('li');    li.className = value ? 'pass' : 'fail';    li.appendChild(document.createTextNode(desc));    document.getElementById('results').appendChild(li);}// 断言函数function assert(value, desc) {    if (value) {        console.log(`\033[32m ${desc} \033[0m`);    // 断言通过 绿色字体    } else {        console.log(`\033[31m ${desc} \033[0m`);    // 断言失败 红色字体    }}
Function
    • JavaScript是一门函数式语言

    • 在JavaScript中,函数是第一型对象。函数可以共处,可以视作为其他任意类型的对象。就像普通的JavaScript数据类型,,函数可以被任意变量进行引用,或声明成对象字面量,甚至可以将其作为函数参数进行传递。

    • 函数是第一型对象
      • Can be created by the literal amount.
      • You can assign properties to variables, arrays, or other objects.
      • Can be passed as a parameter to a function.
      • Can be returned as a function's return value.
      • You can have properties that are dynamically created and assigned values.
    • 命名一个函数时,该名称在整个函数声明范围内是有效的。如果函数声明在顶层,window对象上的同名属性则会引用到该函数。

    • 所有的函数都有一个name属性,该属性保存的是该函数名称的字符串。匿名函数的name属性值为空。

    • 在JavaScript中,作用域是由function进行声明的,而不是代码块。声明的作用域创建于代码块,但不是终结于代码块(其他语言是终结于代码块的)

if (window) {    var x = 123;}alert(x);执行代码后,会弹出123,是因为JavaScript在大括号关闭处并没有终止其作用域。
    • 变量声明的作用域开始于声明的地方,结束于函数的结尾,与代码嵌套无关。

    • 命名函数的作用域是指声明该函数的整个函数范围,与代码嵌套无关;

    • 对于作用域声明,全局上下文就像一个包含页面所有代码的超大型函数。

    • 所有的函数调用都会传递两个隐式参数:argument和this

Called as a function

If a number is not invoked as a method, a constructor, or through apply () or call (), it is considered to be called as a function.

function ninja() {};ninja()var samurai = function() {};samurai()
    • 以这种方式调用时,函数的上下文是全局上下文---window对象。
Called as a method

When a function is assigned to a property of an object and is invoked using this property that references the function, the function is invoked as a method of that object.

var 0 = {};o.whatever = function() {};o.whatever();
    • 将函数作为对象的一个方法进行调用时,该对象就变成了函数上下文,并且在函数内部可以以this参数的形式进行访问。
Called as a constructor
    • 将函数作为构造器进行调用,需要在函数调用前使用new关键字
      • Creates a new empty object;
      • The object that is passed to the constructor is the this parameter, which becomes the function context of the constructor;
      • If no value is explicitly returned, the newly created object is returned as the constructor's return value.
      function Ninja() {    this.skulk = function() { return this; }}var ninja1 = new Ninja();var ninja2 = new Ninja();
      • 构造器的目的是通过函数调用初始化创建新的对象。
function call Mode differences
    • 函数调用方式之间点主要差异是:作为this参数传递给执行函数的上下文对象之间点区别。
      • As a method invocation, the context is the owner of the method;
      • Called as a global function, the context is always window (that is, the function is a method of window).
      • Called as a constructor, whose context object is the newly created object instance.
Use the Apply () and call () methods
    • 通过函数的apply()方法来调用函数,需要给apply()传入两个参数:一个是函数上下文的对象,另一个是作为函数参数所组成的数组;
    • 通过函数的call()方法来调用函数,需要给call()传入两个参数:一个是函数上下文的对象,另一个是作为函数参数的参数列表,而不是单个数组;
function juggle() {    var result = 0;    for (var n = 0; n < arguments.length; n++) {        result += arguments[n]    }    this.result = result;}var ninja1 = {};var ninja2 = {};juggle.apply(ninja1, [1,2,3,4]);juggle.call(ninja2, 5,6,7,8)assert(ninja1.result === 10, 'juggled via apply');assert(ninja2.result === 26, 'juggled via call');
    • 使用apply()和call()可以选择任意对象作为函数上下文;
Function Summary
    • function is the first type object;
      • Created by the literal amount.
      • Assigns a value to a variable or property.
      • Passed as a parameter.
      • Returned as the result of the function.
      • Owns properties and methods.
    • The function is created by the literal, and its name is optional.
    • During the page life cycle, the browser can invoke functions as various types of event handlers.
    • The scope of the variable starts at the declaration and ends at the end of the function, which crosses the domain boundary (for example: curly braces)
    • An intrinsic function is available (lifted) anywhere in the current function, even if it is referenced in advance.
    • The length of a function's formal parameter list and the actual argument list can be different.
      • Unassigned parameters are set to undefined.
      • The extra parameter is not bound to the parameter name.
    • Each function call will pass in two implicit arguments.
      • Arguments, the actual passed-in parameter collection.
      • This, as the object reference for the function context.
    • function calls can be made in different ways, and different invocation mechanisms determine the different function contexts.
      • When called as a normal function, its context is a Global object (window).
      • When invoked as a method, its context is the object that owns the method.
      • When invoked as a constructor, its context is the newly allocated object instance.
      • The context can be set to any value when called by the function's apply () or call () method.
anonymous functions
    • 为了不让不必要的函数名称污染全局命名空间,可以创建大量的小型函数进行传递,而不是创建包含大量命令语句的大型函数。
Recursive
    • 递归:当函数调用自身,或调用另外一个函数,但这个函数的调用树中的某个地方又调用到了自己时,就产生了递归。

    • 递归的两个条件:引用自身,并且有终止条件。

Closed Package
    • 闭包是一个函数在创建时允许自身函数访问并操作该自身函数之外的变量时所创建的作用域

    • 闭包可以让函数访问所有的变量和函数,只要这些变量和函数存在于该函数声明时的作用域内就行。

var outerValue = 'ninja';var later;function outerFunction() {    // 该变量的作用域限制在该函数内部,并且在函数外部访问不到;    var innerValue = 'samurai';    // 在外部函数内,声明一个内部函数。    // 注意:声明该函数时,innerValue是在作用域内的    function innerFunction() {        assert(outerValue, 'I can see the ninja');        assert(innerValue, 'I can see the samurai');        // 将内部函数引用到later变量上,由于later在全局作用域内,所以可以对它进行调用。        later = innerFunction;    }}// 调用外部函数,将会声明内部函数,并将内部函数赋值给later变量。outerFunction();// 通过later调用内部函数。// 我们不能直接调用内部函数,因为它的作用域(和innerValue一起)被限制在outerFunction内。later();
Closure usage scenarios: private variables
    • 在构造器内隐藏变量,使其在外部作用域不可访问,但是可以存在于闭包内。
function Ninja() {    var feints = 0;    this.getFenits = function() {        return feints;    }    this.feint = function() {        feints++;    }}var ninja = new Ninja();ninja.feint();assert(ninja.getFenits() === 1, '调用一次,内部变量++');assert(ninja.feints === undefined, '函数外部不可访问')
    • 变量的作用域依赖于变量所在的闭包

    • 闭包记住的是变量的引用,而不是闭包创建时刻该变量的值

Prototypes and object-oriented
    • 所有的函数在初始化时都有一个prototype属性,该属性的初始值是一个空对象。
    • 使用new操作符将函数作为构造器进行调用的时候,其上下文被定义为新对象的实例。
    • 在构造器内的绑定操作优先级永远高于在原型上的绑定操作优先级。因为构造器的this上下文指向的是实例自身,所以我们可以在构造器内对核心内容执行初始化操作。

    • 通过instanceof操作,可以判断函数是否继承了其原型链中任何对象的功能。

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.