精华内容
下载资源
问答
  • JavaScript语言学习

    2018-12-21 15:40:26
    JavaScript学习传送门 JavaScript入门:http://es6.ruanyifeng.com/ ...JavaScript标准:https://wangdoc.com/javascript/ 《JavaScript语言精粹(修订版)》: http://item.jd.com/11090963.html...

    JavaScript学习传送门

    JavaScript入门:http://es6.ruanyifeng.com/

    JavaScript标准:https://wangdoc.com/javascript/

    《JavaScript语言精粹(修订版)》: http://item.jd.com/11090963.html

    展开全文
  • JavaScript对象

    2020-08-19 10:47:19
    重要说明:本教程已经搬迁,此处不再维护,请访问新网址:wangdoc.com/javascript。 概述 生成方法 对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。 什么是对象?简单说,对象就是一组...

    目录

    重要说明:本教程已经搬迁,此处不再维护,请访问新网址:wangdoc.com/javascript

    概述

    生成方法

    对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。

    什么是对象?简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

    var obj = {
      foo: 'Hello',
      bar: 'World'
    };
    

    上面代码中,大括号就定义了一个对象,它被赋值给变量obj,所以变量obj就指向一个对象。该对象内部包含两个键值对(又称为两个“成员”),第一个键值对是foo: 'Hello',其中foo是“键名”(成员的名称),字符串Hello是“键值”(成员的值)。键名与键值之间用冒号分隔。第二个键值对是bar: 'World'bar是键名,World是键值。两个键值对之间用逗号分隔。

    键名

    对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。上面的代码也可以写成下面这样。

    var obj = {
      'foo': 'Hello',
      'bar': 'World'
    };
    

    如果键名是数值,会被自动转为字符串。

    var obj = {
      1: 'a',
      3.2: 'b',
      1e2: true,
      1e-2: true,
      .234: true,
      0xFF: true
    };
    
    obj
    // Object {
    //   1: "a",
    //   3.2: "b",
    //   100: true,
    //   0.01: true,
    //   0.234: true,
    //   255: true
    // }
    
    obj['100'] // true
    

    上面代码中,对象obj的所有键名虽然看上去像数值,实际上都被自动转成了字符串。

    如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。

    // 报错
    var obj = {
      1p: 'Hello World'
    };
    
    // 不报错
    var obj = {
      '1p': 'Hello World',
      'h w': 'Hello World',
      'p+q': 'Hello World'
    };
    

    上面对象的三个键名,都不符合标识名的条件,所以必须加上引号。

    对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

    var obj = {
      p: function (x) {
        return 2 * x;
      }
    };
    
    obj.p(1) // 2
    

    上面代码中,对象obj的属性p,就指向一个函数。

    如果属性的值还是一个对象,就形成了链式引用。

    var o1 = {};
    var o2 = { bar: 'hello' };
    
    o1.foo = o2;
    o1.foo.bar // "hello"
    

    上面代码中,对象o1的属性foo指向对象o2,就可以链式引用o2的属性。

    对象的属性之间用逗号分隔,最后一个属性后面可以加逗号(trailing comma),也可以不加。

    var obj = {
      p: 123,
      m: function () { ... },
    }
    

    上面的代码中,m属性后面的那个逗号,有没有都可以。

    属性可以动态创建,不必在对象声明时就指定。

    var obj = {};
    obj.foo = 123;
    obj.foo // 123
    

    上面代码中,直接对obj对象的foo属性赋值,结果就在运行时创建了foo属性。

    对象的引用

    如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。

    var o1 = {};
    var o2 = o1;
    
    o1.a = 1;
    o2.a // 1
    
    o2.b = 2;
    o1.b // 2
    

    上面代码中,o1o2指向同一个对象,因此为其中任何一个变量添加属性,另一个变量都可以读写该属性。

    此时,如果取消某一个变量对于原对象的引用,不会影响到另一个变量。

    var o1 = {};
    var o2 = o1;
    
    o1 = 1;
    o2 // {}
    

    上面代码中,o1o2指向同一个对象,然后o1的值变为1,这时不会对o2产生影响,o2还是指向原来的那个对象。

    但是,这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量这时都是值的拷贝。

    var x = 1;
    var y = x;
    
    x = 2;
    y // 1
    

    上面的代码中,当x的值发生变化后,y的值并不变,这就表示yx并不是指向同一个内存地址。

    表达式还是语句?

    对象采用大括号表示,这导致了一个问题:如果行首是一个大括号,它到底是表达式还是语句?

    { foo: 123 }
    

    JavaScript 引擎读到上面这行代码,会发现可能有两种含义。第一种可能是,这是一个表达式,表示一个包含foo属性的对象;第二种可能是,这是一个语句,表示一个代码区块,里面有一个标签foo,指向表达式123

    为了避免这种歧义,V8 引擎规定,如果行首是大括号,一律解释为对象。不过,为了避免歧义,最好还是在大括号前加上圆括号。

    ({ foo: 123})
    

    这种差异在eval语句(作用是对字符串求值)中反映得最明显。

    eval('{foo: 123}') // 123
    eval('({foo: 123})') // {foo: 123}
    

    上面代码中,如果没有圆括号,eval将其理解为一个代码块;加上圆括号以后,就理解成一个对象。

    属性的操作

    读取属性

    读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。

    var obj = {
      p: 'Hello World'
    };
    
    obj.p // "Hello World"
    obj['p'] // "Hello World"
    

    上面代码分别采用点运算符和方括号运算符,读取属性p

    请注意,如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。

    var foo = 'bar';
    
    var obj = {
      foo: 1,
      bar: 2
    };
    
    obj.foo  // 1
    obj[foo]  // 2
    

    上面代码中,引用对象objfoo属性时,如果使用点运算符,foo就是字符串;如果使用方括号运算符,但是不使用引号,那么foo就是一个变量,指向字符串bar

    方括号运算符内部还可以使用表达式。

    obj['hello' + ' world']
    obj[3 + 3]
    

    数字键可以不加引号,因为会自动转成字符串。

    var obj = {
      0.7: 'Hello World'
    };
    
    obj['0.7'] // "Hello World"
    obj[0.7] // "Hello World"
    

    上面代码中,对象obj的数字键0.7,加不加引号都可以,因为会被自动转为字符串。

    注意,数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。

    var obj = {
      123: 'hello world'
    };
    
    obj.123 // 报错
    obj[123] // "hello world"
    

    上面代码的第一个表达式,对数值键名123使用点运算符,结果报错。第二个表达式使用方括号运算符,结果就是正确的。

    属性的赋值

    点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。

    var obj = {};
    
    obj.foo = 'Hello';
    obj['bar'] = 'World';
    

    上面代码中,分别使用点运算符和方括号运算符,对属性赋值。

    JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。

    var obj = { p: 1 };
    
    // 等价于
    
    var obj = {};
    obj.p = 1;
    

    查看所有属性

    查看一个对象本身的所有属性,可以使用Object.keys方法。

    var obj = {
      key1: 1,
      key2: 2
    };
    
    Object.keys(obj);
    // ['key1', 'key2']
    

    delete 命令

    delete命令用于删除对象的属性,删除成功后返回true

    var obj = { p: 1 };
    Object.keys(obj) // ["p"]
    
    delete obj.p // true
    obj.p // undefined
    Object.keys(obj) // []
    

    上面代码中,delete命令删除对象objp属性。删除后,再读取p属性就会返回undefined,而且Object.keys方法的返回值也不再包括该属性。

    注意,删除一个不存在的属性,delete不报错,而且返回true

    var obj = {};
    delete obj.p // true
    

    上面代码中,对象obj并没有p属性,但是delete命令照样返回true。因此,不能根据delete命令的结果,认定某个属性是存在的。

    只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

    var obj = Object.defineProperty({}, 'p', {
      value: 123,
      configurable: false
    });
    
    obj.p // 123
    delete obj.p // false
    

    上面代码之中,对象objp属性是不能删除的,所以delete命令返回false(关于Object.defineProperty方法的介绍,请看《标准库》的 Object 对象一章)。

    另外,需要注意的是,delete命令只能删除对象本身的属性,无法删除继承的属性(关于继承参见《面向对象编程》章节)。

    var obj = {};
    delete obj.toString // true
    obj.toString // function toString() { [native code] }
    

    上面代码中,toString是对象obj继承的属性,虽然delete命令返回true,但该属性并没有被删除,依然存在。这个例子还说明,即使delete返回true,该属性依然可能读取到值。

    in 运算符

    in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false

    var obj = { p: 1 };
    'p' in obj // true
    

    in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。

    var obj = {};
    'toString' in obj // true
    

    上面代码中,toString方法不是对象obj自身的属性,而是继承的属性。但是,in运算符不能识别,对继承的属性也返回true

    for…in 循环

    for...in循环用来遍历一个对象的全部属性。

    var obj = {a: 1, b: 2, c: 3};
    
    for (var i in obj) {
      console.log(obj[i]);
    }
    // 1
    // 2
    // 3
    

    下面是一个使用for...in循环,提取对象属性名的例子。

    var obj = {
      x: 1,
      y: 2
    };
    var props = [];
    var i = 0;
    
    for (var p in obj) {
      props[i++] = p
    }
    
    props // ['x', 'y']
    

    for...in循环有两个使用注意点。

    • 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
    • 它不仅遍历对象自身的属性,还遍历继承的属性。

    举例来说,对象都继承了toString属性,但是for...in循环不会遍历到这个属性。

    var obj = {};
    // toString 属性是存在的
    obj.toString // toString() { [native code] }
    
    for (var p in obj) {
      console.log(p);
    } // 没有任何输出
    

    上面代码中,对象obj继承了toString属性,该属性不会被for...in循环遍历到,因为它默认是“不可遍历”的。关于对象属性的可遍历性,参见《标准库》章节中 Object 一章的介绍。

    如果继承的属性是可遍历的,那么就会被for...in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。

    var person = { name: '老张' };
    
    for (var key in person) {
      if (person.hasOwnProperty(key)) {
        console.log(key);
      }
    }
    // name
    

    with 语句

    with语句的格式如下:

    with (对象) {
      语句;
    }
    

    它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

    // 例一
    var obj = {
      p1: 1,
      p2: 2,
    };
    with (obj) {
      p1 = 4;
      p2 = 5;
    }
    // 等同于
    obj.p1 = 4;
    obj.p2 = 5;
    
    // 例二
    with (document.links[0]){
      console.log(href);
      console.log(title);
      console.log(style);
    }
    // 等同于
    console.log(document.links[0].href);
    console.log(document.links[0].title);
    console.log(document.links[0].style);
    

    注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。

    var obj = {};
    with (obj) {
      p1 = 4;
      p2 = 5;
    }
    
    obj.p1 // undefined
    p1 // 4
    

    上面代码中,对象obj并没有p1属性,对p1赋值等于创造了一个全局变量p1。正确的写法应该是,先定义对象obj的属性p1,然后在with区块内操作它。

    这是因为with区块没有改变作用域,它的内部依然是当前作用域。这造成了with语句的一个很大的弊病,就是绑定对象不明确。

    with (obj) {
      console.log(x);
    }
    

    单纯从上面的代码块,根本无法判断x到底是全局变量,还是对象obj的一个属性。这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,只能留到运行时判断,这就拖慢了运行速度。因此,建议不要使用with语句,可以考虑用一个临时变量代替with

    with(obj1.obj2.obj3) {
      console.log(p1 + p2);
    }
    
    // 可以写成
    var temp = obj1.obj2.obj3;
    console.log(temp.p1 + temp.p2);
    

     转自https://javascript.ruanyifeng.com/grammar/object.html

    展开全文
  • JavaScript随记

    2021-01-17 07:54:57
    https://wangdoc.com/javascript/index.html 基本语法中所到的知识: 变量提升的理解: JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的...

    https://wangdoc.com/javascript/index.html

    基本语法中所到的知识:

    变量提升的理解:

    JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。

    console.log(a);
    var a = 1;
    

    上面代码首先使用console.log方法,在控制台(console)显示变量a的值。这时变量a还没有声明和赋值,所以这是一种错误的做法,但是实际上不会报错。因为存在变量提升,真正运行的是下面的代码。

    var a;
    console.log(a);
    a = 1;
    

    最后的结果是显示undefined,表示变量a已声明,但还未赋值。


    需要注意的是,-->只有在行首,才会被当成单行注释,否则会当作正常的运算

    function countdown(n) {
      while (n --> 0) console.log(n);
    }
    countdown(3)
    // 2
    // 1
    // 0
    

    经测试,理解上应该是:n–,n>0时进行一直执行。 不规范的写法


    区块

    JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。

    对于var命令来说,JavaScript 的区块不构成单独的作用域(scope)。

    {
      var a = 1;
    }
    a // 1
    

    上面代码在区块内部,使用var命令声明并赋值了变量a,然后在区块外部,变量a依然有效,区块对于var命令不构成单独的作用域,与不使用区块的情况没有任何区别。在 JavaScript 语言中,单独使用区块并不常见,区块往往用来构成其他更复杂的语法结构,比如forifwhilefunction


    执行语句中

    注意,if后面的表达式之中,不要混淆赋值表达式(=)、严格相等运算符(===)和相等运算符(==)。尤其是赋值表达式不具有比较作用。

    var x = 1;
    var y = 2;
    if (x = y) {
      console.log(x);
    }
    // "2"
    

    相当于执行

    var x = 1;
    var y = 2;
    if (x = y) {     --------> 将y的值赋值给x,然后进行if(x), 然后进行执行。
      console.log(x);
    }
    // "2"
    

    上面代码的原意是,当x等于y的时候,才执行相关语句。但是,不小心将严格相等运算符写成赋值表达式,结果变成了将y赋值给变量x,再判断变量x的值(等于2)的布尔值(结果为true)。

    这种错误可以正常生成一个布尔值,因而不会报错。为了避免这种情况,有些开发者习惯将常量写在运算符的左边,这样的话,一旦不小心将相等运算符写成赋值运算符,就会报错,因为常量不能被赋值。

    if (x = 2) { // 不报错
    if (2 = x) { // 报错
    

    switch语句:中在case中选项结果中必须含有break,否则会执行所有的语句。

    JavaScript语言允许,语句的前面有标签(lable),相当于定位符,用于跳转到程序的任意位置。标签可以是任意字符,但是不能是保留字,语句部分可以是任意语句,标签通常与break语句和continue语句配合使用,跳出指定循环。

    top:
      for (var i = 0; i < 3; i++){
        for (var j = 0; j < 3; j++){
          if (i === 1 && j === 1) break top;
          console.log('i=' + i + ', j=' + j);
        }
      }
    

    1、javaScript数据类型:

    number, string, boolean, undefined, null, Object(对象),

    number,string,boolean,为原始数据类型,为基本数据类型,不能再分割,undefined,null一般为两个特殊值,

    对象是最复杂的数据类型,可以分为三个子类型。对象可以作为其他数据类型的容器。

    狭义的对象(object)数组(array)函数(function)

    2、typeof运算符:

    JavaScript 有三种方法,可以确定一个值到底是什么类型。

    • typeof运算符
    • instanceof运算符
    • Object.prototype.toString方法

    typeof运算符可以返回一个值的数据类型。数值、字符串、布尔值分别返回numberstringboolean

    利用这一点,typeof可以用来检查一个没有声明的变量,而不报错

    v
    // ReferenceError: v is not defined
    
    typeof v
    // "undefined"
    
    // 错误的写法
    if (v) {
      // ...
    }
    // ReferenceError: v is not defined
    
    // 正确的写法
    if (typeof v === "undefined") {
      // ...
    }
    

    其中:使用typeof对空数组进行类别判断,则返回的类型是object,这表示在JavaScript内部,数组本质上是一种特殊的对象,instanceof可以区分数组和对象,

    使用typeof对null进行判断,返回object,由于历史原因造成的,

    typeof window // "object"
    typeof {} // "object"
    typeof [] // "object"
    var o = {};
    var a = [];
    
    o instanceof Array // false
    a instanceof Array // true
    
    typeof null // "object"
    

    null的类型是object,这是由于历史原因造成的。1995年的 JavaScript 语言第一版,只设计了五种数据类型(对象、整数、浮点数、字符串和布尔值),没考虑null,只把它当作object的一种特殊值。后来null独立出来,作为一种单独的数据类型,为了兼容以前的代码,typeof null返回object就没法改变了。


    对于null和undefined的理解,

    null表示空值,即该处的值现在为空。调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空。比如,某个函数接受引擎抛出的错误作为参数,如果运行过程中未出错,那么这个参数就会传入null,表示未发生错误。

    undefined表示“未定义”,下面是返回undefined的典型场景。

    // 变量声明了,但没有赋值
    var i;
    i // undefined
    
    // 调用函数时,应该提供的参数没有提供,该参数等于 undefined
    function f(x) {
      return x;
    }
    f() // undefined
    
    // 对象没有赋值的属性
    var  o = new Object();
    o.p // undefined
    
    // 函数没有返回值时,默认返回 undefined
    function f() {}
    f() // undefined
    
    布尔值

    布尔值代表“真”和“假”两个状态。“真”用关键字true表示,“假”用关键字false表示。布尔值只有这两个值。

    其中,一下运算符会返回布尔值:

    前置逻辑运算符:!(Not),
    相等运算符:===,!==,==,!=
    比较运算符:>,>=,<,<=
    
    

    布尔值的数据类型的转换需要好好了解一下

    如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true

    • undefined
    • null
    • false
    • 0
    • NaN
    • ""''(空字符串)

    注意,空数组([])和空对象({})对应的布尔值,都是true

    if ('') {
      console.log('true');
    }
    // 没有任何输出
    if ([]) {
      console.log('true');
    }
    // true
    
    if ({}) {
      console.log('true');
    }
    // true
    
    展开全文
  • JavaScript Codes

    2019-08-20 17:51:27
    Natve Codes斐波那契数列拷贝阮一峰 https://wangdoc.com/javascript/stdlib/attributes.html实现Object.create() 斐波那契数列 function fib(num) { if (num === 0) return 0; if (num === 1) return 1; return ...

    JavaScript Codes

    数列

    1 在Javascript中什么是伪(类)数组?如何将伪数组转化为标准数组?

    伪数组具有以下特点的对象:

    • 按索引方式存储数据;
    • 具有length属性;
    • 没有数组的push、shift、pop等方法;
      如function的arguments对象,还有getElementsByTagName、ele.childNodes等返回的NodeList对象,或者自定义的某些对象,这些都可以是伪数组。如:
    var guiseArr={
        '0':"AAA",
        '1':"BBB",
        '2':"CCC",
        length:3
    }
    

    我们可以通过以下几种方式将伪数组转换为标准数组:

    //第一种方法,使用slice
    Array.prototype.slice.call(arr,0);
    //第二种方法,直接使用for循环
    var newArr=[];
    for(var i=0;i<arr.length;i++){
        newArr=arr[i];
    }
    //第三种方法,使用ES6的Array.from() 方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。
    var newArr=Array.from(arr);
    //f附加:Array.from(object, mapFunction, thisValue)
    var arr = Array.from([1, 2, 3], x => x * 10);
    // arr[0] == 10;
    // arr[1] == 20;
    // arr[2] == 30;
    

    获取字符串中频率最高的字符

    let str = "ahbbccdeddcccddfg";
    
    String.prototype.getMostOften = function () {
      let str = this;
      let obj = {};
      let max = 0;
    
      for (let i = 0; i < str.length; i++) {//记录各字符串及对应次数
        if (obj[str[i]]) {
          obj[str[i]]++
        } else {
          obj[str[i]] = 1
        }
      };
    
      for (let key in obj) {//记录最大次数
        max = max < obj[key] ? obj[key] : max
      }
    
      for (let key in obj) {//输出最大次数及对应字符
        if (obj[key] === max) {
          console.log(`最多的字符是${key},一共出现了${max}次`);
        }
      }
    }
    
    str.getMostOften();//最多的字符是c,一共出现了5次  最多的字符是d,一共出现了5次
    

    斐波那契数列

    function fib(num) {
      if (num === 0) return 0;
      if (num === 1) return 1;
      return fib(num - 2) + fib(num - 1);//arguments.callee(num-2)+arguments.callee(num-1);
    }
    
    fib(6) // 8
    

    取数组的最大值(ES5、ES6)?

    答:

    //ES5 的写法
        Math.max.apply(null, [14, 3, 77, 30]);
        
        //ES6 的写法
        Math.max(...[14, 3, 77, 30]);
        //reduce
        [14, 3, 77, 30].reduce((accumulator, currentValue) => {
          return accumulator = accumulator > currentValue ? accumulator : currentValue
        });
    
    

    附注:reduce()

    https://www.jianshu.com/p/541b84c9df90

    多维数组降维:

    	var array = [1, [2], [3, [4, [5]]]];
    	array.toString().split(',')//["1", "2", "3", "4", "5"]  注意光是split不够得 会将数字转为字符串 需要处理
    	array.toString().split(',').map(e=>+e)//[1, 2, 3, 4, 5]
    
    //reduce()
    	function flat(arr){
    		return arr.reduce(
    		(pre,item) => pre.concat(Array.isArray(item) ? flat(item) : item),
    		[]
    		)
    	}
    //redue()
    	const flattenDeep = (arr) => Array.isArray(arr)
    	  ? arr.reduce( (a, b) => [...a, ...flattenDeep(b)] , [])
    	  : [arr]
    
    

    用js实现随机选取10–100之间的10个数字,存入一个数组,并排序

    var arr = [];
    function getRandom(start, end) {
      return Math.floor(Math.random() * (end - start + 1) + start)
    };
    var i = 10;
    while (i) {
      arr.push(getRandom(10, 100))
      i--;
    };
    arr.sort()
    
    

    ES5

    new

    作用:

    • 创建一个空对象,继承构造函数原型,并且this引用该对象,
    • 属性与方法被加入到this引用的对象中
    • 新建的对象由this引用,最后隐式返回this

    步骤:

    使用new命令时,它后面的函数依次执行下面的步骤。

    • 创建一个空对象,作为将要返回的对象实例。
    • 将这个空对象的原型,指向构造函数的prototype属性。
    • 将这个空对象赋值给函数内部的this关键字。
    • 开始执行构造函数内部的代码。

    注意事项:

    如果构造函数内部有return语句,且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。

    new命令内部流程

    function _new(constructor, params) {
      let args = [].slice.call(arguments, 1);
      let obj = Object.create(constructor.prototype);
      let ctx = constructor.apply(obj, args);
      return (typeof ctx === 'object' && ctx != null) ? ctx : obj
    }
    

    代码详解:

    function _new(/* 构造函数 */ constructor, /* 构造函数参数 */ params) {
      var args = [].slice.call(arguments);// 将 arguments 对象转为数组
      console.log(args); // [ƒ, "张三", 28]
    
      var constructor = args.shift();// 取出构造函数
      console.log(constructor); //ƒ () {this.price = 1000;return { price: 2000 };}
    
      console.log(constructor.prototype);//{color: "red", constructor: ƒ}
      var context = Object.create(constructor.prototype); // 创建一个空对象,继承构造函数的 prototype 属性 实现context.__proto__ == constructor.prototype
      console.log(context);//Father {} 见下图
      console.log(context.price);//undefined 
    
      var result = constructor.apply(context, args);  // 执行构造函数  进行属性添加  并捕捉有可能返回的返回值
      console.log(context);//Father {price: 1000} 见下图
      console.log(context.price);//1000
      console.log(result);//{price: 2000}
      
      return (typeof result === 'object' && result != null) ? result : context;  // 如果返回结果是对象,就直接返回,否则返回 context 对象
    }
    var Father = function () {
      this.price = 1000;
      return { price: 2000 };
    };
    Father.prototype.color = 'red'
    // 实例
    var chid = _new(Father, '张三', 28);
    console.log(chid)//{price: 2000}
    

    在这里插入图片描述

    JS如何实现继承

    步骤:

    第一步是在子类的构造函数中,调用父类的构造函数。

    第二步,是让子类的原型指向父类的原型,这样子类就可以继承父类原型。

    ES5

    function Afn(Aname){
      this.name = Aname;
      this.gender = '男'
    };
    Afn.prototype.sayName = function(){console.log(this.name +''+this.gender)};
    
    function Bfn(Bname,age){
      Afn.apply(this,arguments);
      this.age = age//自定义
    };
    
    Bfn.prototype = Object.create(Afn.prototype) //或者  Bfn.prototype = new Afn()
    Bfn.prototype.sayAge = ()=>{console.log(this.age)}//自定义  非法
    
    let bfn = new Bfn('henry',12)
    
    bfn.sayName()//henry男 
    bfn.sayAge()//undefined this指向了window(箭头函数this为定义时的所在环境对象)
    console.log(bfn instanceof Bfn);//true
    console.log(bfn instanceof Afn);//true
    console.log(Bfn instanceof Afn);//fals
    

    ES6

    class Afn{
      constructor(name){
        this.name = name;
        this.gender = '女';
        this.body = '漂亮'
      };
      sayName(){console.log(this.name +''+this.gender)};
      getBody(){return this.body}
    }
    
    class Bfn extends Afn{
      constructor(name,age){
        super(name);
        this.age = age;
      };
      getBody(){console.log(this.age + '岁,真'+super.getBody() +'!');
      }
    }
    
    let bfn = new Bfn('小黄',17)
    
    bfn.sayName()//小黄女
    bfn.getBody()//17岁,真漂亮!
    console.log(bfn instanceof Bfn);//true
    console.log(bfn instanceof Afn);//true
    console.log(Bfn instanceof Afn);//false
    

    单个方法继承

    上面代码中,子类是整体继承父类。有时只需要单个方法的继承,这时可以采用下面的写法。

        ClassB.prototype.print = function() {
          ClassA.prototype.print.call(this);
          // some code
        }
    

    上面代码中,子类B的print方法先调用父类A的print方法,再部署自己的代码。这就等于继承了父类A的print方法。

    多重继承

    JavaScript 不提供多重继承功能,即不允许一个对象同时继承多个对象。但是,可以通过变通方法,实现这个功能。

    function M1() {
          this.hello = 'hello';
        }
        
        function M2() {
          this.world = 'world';
        }
        
        function S() {
          M1.call(this);
          M2.call(this);
        }
        
        // 继承 M1
        S.prototype = Object.create(M1.prototype);
        // 继承链上加入 M2
        Object.assign(S.prototype, M2.prototype);
        
        // 指定构造函数
        S.prototype.constructor = S;
        
        var s = new S();
        s.hello // 'hello'
        s.world // 'world'
    

    上面代码中,子类S同时继承了父类M1和M2。这种模式又称为 Mixin(混入)。

    实现Object.create()

    附:Object.create()详解
    原理:让newObj的原型对象是oldObj (以前是这个函数的prototype 那么就让一个构造函数的prototype = oldObj 再new 这个函数即可)

    if (typeof Object.create !== 'function') {
      Object.create = function (obj) {
        function F() {}
        F.prototype = obj;
        return new F();
      };
    }
    

    上面代码表明,Object.create方法的实质是新建一个空的构造函数F,然后让F.prototype属性指向参数对象obj,最后返回一个F的实例,从而实现让该实例继承obj的属性。

    JSONP:
    https://juejin.im/post/5d2547d36fb9a07ea33c3cfd

    深拷贝和浅拷贝

    • 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,浅拷贝只复制对象的第一层属性;

    • 深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。对对象的属性进行递归复制。
      let a = {
      age: 1
      }
      let b = a
      a.age = 2
      console.log(b.age) // 2
      从上述例子中我们可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。

    通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个问题。

    浅拷贝

    对象:

    Object.assign

    Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

    let a = {
        age: 1
    }
    let b = Object.assign({}, a)
    a.age = 2
    console.log(b.age) // 1
    
    展开运算符(…)
      let a = {
            age: 1
        }
        let b = {...a}
        a.age = 2
        console.log(b.age) // 1
    
    赋值实现
    function simpleClone(initalObj) {    
      var obj = {};    
      for(var i in initalObj) {
        obj[i] = initalObj[i];
      }    
      return obj;
    }
    

    数组

    slice
    var arr = [1,2,3,4];
    var arr2 = arr.slice()
    
    concat
    var arr = [1,2,3,4];
    var arr2 = [].concat(arr)
    
    展开运算符(…)

    通常浅拷贝就能解决大部分问题了,但是当我们遇到如下情况就需要使用到深拷贝了

    let a = {
        age: 1,
        jobs: {
            first: 'FE'
        }
    }
    let b = {...a}
    a.jobs.first = 'native'
    console.log(b.jobs.first) // native
    

    浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,那么就又回到刚开始的话题了,两者享有相同的引用。要解决这个问题,我们需要引入深拷贝。

    深拷贝

    添加到Object原型上避免考虑是否是基本数据类型

     Object.prototype.clone = function(){
              var o = this.constructor === Array ? [] : {};
              for(var e in this){
                      o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
              }
              return o;
      }
    

    JSON.parse(JSON.stringify(object))来解决。

    let b = JSON.parse(JSON.stringify(a))
    

    但是该方法也是有局限性的:

    • 会忽略 undefined
    • 会忽略 symbol
    • 会忽略函数
    • 会忽略正则与date对象
    • 不能序列化函数
    let a = {
        age: undefined,
        sex: Symbol('male'),
        jobs: function() {},
        name: 'yck'
    }
    let b = JSON.parse(JSON.stringify(a))
    console.log(b) // {name: "yck"}
    

    你会发现在上述情况中,该方法会忽略掉函数和 undefined 。

    五种常见数据类型递归遍历

    (可以对 JavaScript 中的五种主要数据类型(Number、string、Object、Array、Boolean)进行复制):

    精简版(不考虑性能)
    function deepClone(source) {
      if (typeof obj !== 'object' && obj == null) return;
    
      let target = Array.isArray(source) ? [] : {};
      //let target = obj.constructor === Array ? [] : {}
     
      for (let key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          if (typeof source === 'object' && source != null) {
            target[key] = deepClone(source[key])
          } else {
            target[key] = source[key]
          }
        }
      };
      return target;
    
    };
    
    考虑数组性能用while来做
    function clone(Obj) {  
    		 if (null == obj || "object" != typeof obj) return obj;//考虑到null  基本数据类型直接赋值 
             var buf;   
             if (Obj instanceof Array) {   
                 buf = [];                    //创建一个空的数组
                 var i = Obj.length;   
                 while (i--) {   
                     buf[i] = clone(Obj[i]);   
                 }   
                 return buf;    
             }else (Obj instanceof Object){   
                 buf = {};                   //创建一个空对象
                 for (var k in Obj) {           //为这个对象添加新的属性
                     buf[k] = clone(Obj[k]);   
                 }   
                 return buf;   
             }
         }
    

    考虑到data对象且考虑数组性能用for来做

    function clone(obj) {
        var copy;
     
        // Handle the 3 simple types, and null or undefined
        if (null == obj || "object" != typeof obj) return obj;
     
        // Handle Date
        if (obj instanceof Date) {
            copy = new Date();
            copy.setTime(obj.getTime());
            return copy;
        }
     
        // Handle Array
        if (obj instanceof Array) {
            copy = [];
            for (var i = 0, len = obj.length; i < len; i++) {
                copy[i] = clone(obj[i]);
            }
            return copy;
        }
     
        // Handle Object
        if (obj instanceof Object) {
            copy = {};
            for (var attr in obj) {
                if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
            }
            return copy;
        }
     
        throw new Error("Unable to copy obj! Its type isn't supported.");
    }
    

    定义一个log方法,让它可以代理console.log的方法

    log(){
    	console.log.apply(console,arguments)
    }
    

    如何实现一个 call 函数

    Function.prototype.myCall = function (context) {
      var context = context || window
      // 给 context 添加一个属性
      // getValue.call(a, 'yck', '24') => a.fn = getValue
      context.fn = this
      // 将 context 后面的参数取出来
      var args = [...arguments].slice(1)
      // getValue.call(a, 'yck', '24') => a.fn('yck', '24')
      var result = context.fn(...args)
      // 删除 fn
      delete context.fn
      return result
    }
    

    如何实现一个bind函数

    Function.prototype.myApply = function (context) {
      var context = context || window
      context.fn = this
    
      var result
      // 需要判断是否存储第二个参数
      // 如果存在,就将第二个参数展开
      if (arguments[1]) {
        result = context.fn(...arguments[1])
      } else {
        result = context.fn()
      }
    
      delete context.fn
      return result
    }
    

    如何实现一个bind函数


    ES6

    实现call apply bind

    bind

    简单实现:

    Function.prototype.bind = function(ctx){
    	var _this = this;
    	_this.call(ctx,[].slice.call(arguments,1))
    };
    

    功能封装

    post & get 流程

    var xhr = new XMLHttpRequest();
    
    //get
    xhr.open('GET', url + '?' + params, true);
    xhr.send(null);
    
    //post
    xhr.open('POST', url, true);
    xhr.setRequestHeader('Content-Type', '...');
    xhr.send(params)//username=huanger&password=123
    
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4) {//判断异步调用是否完成
        if (status >= 200 && xhr.status < 300) {判断异步调用是否成功
          success(xhr.responseText || xhr.responseXML);//成功回调函数
        } else {
          fail(xhr.status)失败回调函数
        }
      }
    }
    

    Ajax简单封装

    function Ajax(opts) {
      let url = opts.url;
      let type = (params.type || 'GET').toUpperCase();
      let dataType = opts.dataType || "json";
      let success = opts.success;
      let onerror = opts.onerror;
      let data = opts.data || {};
    
      let dataStr = [];
      for (let key in data) {
        dataStr.push(key + '=' + data[key])
      };
      dataStr = dataStr.join('&');
    
      if (type === 'GET') {
        url += '?' + dataStr
      };
    
    
      let xhr = new XMLHttpRequest();
      xhr.open(type, url, true);
    
      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {//判断异步调用是否完成
          if (status >= 200 && xhr.status < 300) {判断异步调用是否成功
            success(xhr.responseText || xhr.responseXML);//成功回调函数
          } else {
            fail(xhr.status)失败回调函数
          }
        }
      }
    
      if (type == 'GET') {
        xhr.send(null);
      } else {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        xhr.send(dataStr);
      }
    
    }
    
    

    原生JS实现Jq的ready方法?

    function ready(fn){
          if(document.addEventListener) {        //标准浏览器
              document.addEventListener('DOMContentLoaded', function() {
                  //注销事件, 避免反复触发
                  document.removeEventListener('DOMContentLoaded',arguments.callee, false);
                  fn();            //执行函数
              }, false);
          }else if(document.attachEvent) {        //IE
              document.attachEvent('onreadystatechange', function() {
                 if(document.readyState == 'complete') {
                     document.detachEvent('onreadystatechange', arguments.callee);
                     fn();        //函数执行
                 }
             });
         }
     };
    

    封装一个函数,参数是定时器的时间,.then执行回调函数

    function sleep (time) {
        return new Promise((resolve) => setTimeout(resolve, time));
    }
    

    写一段JS程序提取URL中的各个GET参数

    有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数
    (参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:'1', b:'2', c:'', d:'xxx', e:undefined}
    
    function serilizeUrl(url) {
         var result = {};
         url = url.split("?")[1];
         var map = url.split("&");
         for(var i = 0, len = map.length; i < len; i++) {
             result[map[i].split("=")[0]] = map[i].split("=")[1];
         }
         return result;
     }
    

    清除字符串前后的空格

    function trim(str) {
        if (str && typeof str === "string") {
            return str.replace(/(^\s*)|(\s*)$/g,""); //去除前后空白符
        }
    }
    

    实现一个函数,判断输入是不是回文字符串

    function run(input) {
      if (typeof input !== 'string') return false;
      return input.split('').reverse().join('') === input;
    }
    

    时间戳转为日期格式

    //时间戳转换为自定义年月日时分秒时间格式:
    //number :传入时间戳  时间戳为10位需*1000,时间戳为13位的话不需乘1000
    //format :返回格式,支持自定义 但参数必须与formatArr里保持一致
    function formatTime(number, format) {
      //格式化日期函数,如月、日、时、分、秒保证为2位数
      function formatNumber(n) {
        n = n.toString()
        return n[1] ? n : '0' + n
      }
      let date = new Date(number) //转为时间对象  不带参数的话返回当前日期
      let newArr = []
      let formatArr = ['Y', 'M', 'D', 'h', 'm', 's']
    
      newArr.push(formatNumber(date.getFullYear()))
      newArr.push(formatNumber(date.getMonth() + 1))
      newArr.push(formatNumber(date.getDate()))
    
      newArr.push(formatNumber(date.getHours()))
      newArr.push(formatNumber(date.getMinutes()))
      newArr.push(formatNumber(date.getSeconds()))
    
      for (let i = 0; i < newArr.length; i++) {
        format = format.replace(formatArr[i], newArr[i])  //字符串一一对应替换
      }
      return format
    }
    var timestamp = 1488481383;//时间戳
    console.log(formatTime(timestamp, 'Y/M/D h:m:s'));//转换为日期:2017/03/03 03:03:03
    console.log(formatTime(timestamp * 1000, 'h:m'));//转换为日期:03:03
    

    DOM

    写一个函数,批量操作 css。

    function css(node, styleObj) {
      //补全
    }
    css(document.body, {
      "color": "red",
      "background-color": "#ccc"
    })
    

    答:

    function css(node, styleObj) {
      for(key in styleObj) {
        node.style[key] = styleObj[key]
      }
    }
    css(document.body, {
      "color": "red",
      "background-color": "#ccc"
    })
    
    

    补全代码,要求:当鼠标放置在 li 元素上,会在 img-preview 里展示当前 li 元素的 data-img 对应的图片。

    <ul class="ct">
      <li data-img="1.png">鼠标放置查看图片1</li>
      <li data-img="2.png">鼠标放置查看图片2</li>
      <li data-img="3.png">鼠标放置查看图片3</li>
    </ul>
    <div class="img-preview"></div>
    <script>
    //补全
    </script>
    

    答:

    <script>
      var list = document.querySelector(".ct");
      var preview = document.querySelector(".img-preview");
      var newimg = document.createElement("img");
    
      list.addEventListener("mouseover", function(e) {
        if(e.target.tagName.toLowerCase() === "li") {
           newimg.src = e.target.getAttribute("data-img");
           preview.appendChild(newimg);
        }
      });
    
      list.addEventListener("mouseout", function() {
        preview.removeChild(newimg);
      });
    </script>
    

    取到页面中所有的checkbox

    var domList = document.getElementsByTagName(‘input’)
     var checkBoxList = [];
     var len = domList.length;  //缓存到局部变量
     while (len--) {  //使用while的效率会比for循环更高
       if (domList[len].type == ‘checkbox’) {
           checkBoxList.push(domList[len]);
       }
     }
    

    想实现一个对页面某个节点的拖曳?如何做?(使用原生JS)

    • 给需要拖拽的节点绑定mousedown, mousemove, mouseup事件
    • mousedown事件触发后,开始拖拽
    • mousemove时,需要通过event.clientX和clientY获取拖拽位置,并实时更新位置
    • mouseup时,拖拽结束
    • 需要注意浏览器边界的情况

    下面这个ul,如何点击每一列的时候alert其index

    考察闭包

     <ul id=”test”>
         <li>这是第一条</li>
         <li>这是第二条</li>
         <li>这是第三条</li>
     </ul>
    
    var lis=document.getElementById('2223').getElementsByTagName('li');
     for(var i=0;i<3;i++)
     {
         lis[i].onclick=(function(a){
             return function() {
                 alert(a);
             }
         })(i);
     }
    

    展开全文
  • https://wangdoc.com/javascript/ http://javascript.ruanyifeng.com/ https://www.w3cschool.cn/javascript_guide/
  • JavaScript知识点

    2019-04-30 16:14:54
    https://wangdoc.com/javascript/basic/introduction.html JavaScript 是一种轻量级的脚本语言,用来编写控制其他大型应用程序(比如浏览器)的“脚本”。 JavaScript 也是一种嵌入式(embedded)语言。它本身...
  • JavaScript-导论

    2018-10-29 15:10:00
    来源:https://wangdoc.com/javascript/basic/introduction.html 1.什么是JavaScript语言? JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”(script language),指的是它不具备开发操作系统的能力,而是只...
  • JavaScript 中undefined

    2019-12-21 10:33:12
    如果只是声明变量而没有赋值,则该变量的值是undefined。undefined是一个特殊的值,表示“无定义”。 来源:https://wangdoc.com/javascript/basic/grammar.html
  • JavaScript 语言的历史 网道(WangDoc.com),互联网文档计划 目录 [隐藏] 诞生 JavaScript 与 Java 的关系 JavaScript 与 ECMAScript 的关系 ...https://wangdoc.com/javascript/basic/history.html ...
  • JavaScript语言的历史

    2018-11-07 15:27:00
    原文地址:https://wangdoc.com/javascript/ JavaScript和ECMAScript的关系 1996年11月,Netscape公司决定将JavaScript提交国际标准化组织ECMA,希望JavaScript能够成为国际标准。1997年7月,ECMA组织发布ECMA-262的...
  • 网道-JavaScript 教程:https://wangdoc.com/javascript/ JavaScript 标准参考教程(alpha)-阮一峰:http://javascript.ruanyifeng.com/
  • 内容范围广,解释齐全。 https://wangdoc.com/javascript/index.html
  • 来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录JavaScript的诞生JavaScript与... 重要说明:本教程已经搬迁,此处不再维护,请访问新网址:wangdoc.com/javascriptJavaScript的诞生 JavaScr...
  • 一、学习资料 https://wangdoc.com/javascript/index.html 二、学习笔记 javascript学习笔记(1) 4、语法专题
  • JavaScript里的this

    2019-09-21 20:59:06
    https://wangdoc.com/javascript/oop/this.html JavaScript里的this 知识点 问题来了 解决方案 this在有些地方会让人感觉很困惑,这里记录下。 知识点 this指向谁,是实际运行时才决定的。this指向当前运行...
  • JavaScript严格模式

    2020-08-17 00:03:58
    严格模式网道(WangDoc.com),互联网文档计划【免费领取】廖雪峰老师历时三个月整理的《Vue 源码 + 3.0语法剖析教程》。除了正常的运行模式,JavaScript 还有第二种运行模式:严格模式(strict mode)。顾名思义,...
  • JavaScript Object对象

    2020-08-16 19:43:46
    JavaScript 教程标准库Object 对象 标准库属性描述对象 Object 对象网道(WangDoc.com),互联网文档计划【免费领取】廖雪峰老师历时三个月整理的《Vue 源码 + 3.0语法剖析教程》。目录 [隐藏] 概述 Object() Object...
  • https://wangdoc.com/javascript/
  • 本文MarkDown原文地址为:object.md,完整的文档GitHub地址为:wangdoc/javascript-tutorial 概述 JavaScript 原生提供Object对象(注意起首的O是大写),本章介绍该对象原生的各种方法。 JavaScript 的所有其他对象...
  • JavaScript 实验环境

    2019-05-16 10:33:13
    https://wangdoc.com/javascript/basic/introduction.html#%E5%AE%9E%E9%AA%8C%E7%8E%AF%E5%A2%83 本教程包含大量的示例代码,只要电脑安装了浏览器,就可以用来实验了。读者可以一边读一边运行示例,加深理解。 ...
  • 摘自wangdoc.com,原文地址:https://wangdoc.com/javascript/types/function.html#闭包 闭包(closure)是 Javascript 语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 理解闭包,首先必须理解变量...
  • JavaScript难点整理

    2019-04-14 19:44:00
    https://wangdoc.com/javascript/operators/boolean.html#%E5%8F%96%E5%8F%8D%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%88%EF%BC%89 取反运算符会进行数据类型的转换,将所有的数据类型都转换为布尔数据类型 除了特殊的 ...
  • 1、JavaScript 教程 阮一峰 本教程全面介绍 JavaScript 核心语法,从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。 所有章节都带有大量的代码实例,便于理解和模仿,...来源:https://wangdoc.com/javascript...
  • JavaScript的基本语法

    2018-11-07 16:46:00
    原文地址:https://wangdoc.com/javascript/ 语句 JavaScript程序的执行单位为行,也就是一行一行地执行。一般情况下,每一行就是一个语句。 var a = 1 + 3; 表达式不需要分号结尾。一旦在表达式后面添加分号,则...
  • https://wangdoc.com/javascript/basic/introduction.html JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”(script language),指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序...
  • JavaScript 语言的历史

    2018-10-29 15:25:00
    来源:https://wangdoc.com/javascript/basic/introduction.html 1.诞生 JavaScript 因为互联网而生,紧跟着浏览器的出现而问世。回顾它的历史,就要从浏览器的历史讲起。 1990年底,欧洲核能研究组织(CERN)...
  • JavaScript 的基本语法

    2018-10-29 16:28:00
    来源:https://wangdoc.com/javascript/basic/introduction.html 1. 语句 JavaScript 程序的执行单位为行(line),也就是一行一行地执行。一般情况下,每一行就是一个语句。 语句(statement)是为了完成某种...
  • 参考: https://wangdoc.com/javascript/oop/this.html 一、涵义 不管this用在什么场合,this都有一个共同点:它总是返回一个对象。简单说,this就是属性或方法“当前”所在的对象。总而言之,在JavaScript语言中...
  • JavaScript面向对象编程(二) ...详情请看https://wangdoc.com/javascript/oop/index.html 构造函数 面向对象第一步就是要生成对象,对象的生成需要一个模板,在Java中这个模板是“类”,但JavaScript中,...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 177
精华内容 70
热门标签
关键字:

javascriptwangdoc

java 订阅