JavaScript Class类详解_js class-程序员宅基地

技术标签: ES6  Class  javascript  开发语言  ecmascript  

        ECMAScript 6 提供了更接近传统语言的写法,新引入的class关键字具有正式定义类的能力。类(class)是ECMAScript中新的基础性语法糖结构,虽然ECMAScript 6类表面上看起来可以支持正式的面向对象编程,但实际上它背后使用的仍然是原型和构造函数的概念,让对象原型的写法更加清晰、更像面向对象编程的语法。

欢迎大家到我的掘金上访问,目前基本在掘金社区发展,前端农民晨曦 的个人主页 - 文章 - 掘金


一、类的定义

定义类也有两种主要方式:类声明和类表达式。这两种方式都使用class关键字加大括号:

// 类声明
class Person {}

// 类表达式
const TestPerson = class {}

注意:函数声明类声明之间的一个重要区别在于,函数声明会提升,类声明不会。需要先声明类,然后再访问它,否则就会出现ReferenceError,如:

const test = new Person(); // ReferenceError: Person is not defined

class Person {}

 另一个跟函数声明不同的地方是,函数受函数作用域限制,而类受块作用域限制:

{
    function FunctionDeclaration () {}
    class ClassDeclaration {}
    // 使用var 声明
    var VarClass = class {}
    // 使用let/const 声明
    let LetClass = class {}
}

console.log(FunctionDeclaration) // FunctionDeclaration () {}
console.log(ClassDeclaration) // ReferenceError: ClassDeclaration is not defined
console.log(VarClass) // class {}
console.log(LetClass) // ReferenceError: letClass is not defined

class 类完全可以看成构造函数的另一种写法,这种写法可以让对象的原型属性和函数更加清晰。

class Person {}

console.log(typeof Person) // function
console.log(Person === Person.prototype.constructor) // true

上面代码表明,类的数据类型就是函数,类本身就指向构造函数。

二、类构造函数

constructor 方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。通过 new 关键字生成对象实例时,自动会调用该方法。一个类只能拥有一个名为"constructor"构造函数,不能出现多个,如果定义了多个"constructor"构造函数,则将抛出 一个SyntaxError错误。如果没有定义"constructor"构造函数,class 会默认添加一个空的"constructor"构造函数。

class Person {}

// 等于

class Person {
    constructor () {}
}

使用new操作符实例化Person的操作等于使用new调用其构造函数。唯一可感知的不同之处就是,JavaScript解释器知道使用new和类意味着应该使用constructor函数进行实例化。

类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

class Person {}

Person() // TypeError: Class constructor Test1 cannot be invoked without 'new'

使用new调用类的构造函数会执行如下操作。

  1. 在内存中创建一个新对象;
  2. 这个新对象内部的[[Prototype]]指针被赋值为构造函数的prototype属性;
  3. 构造函数内部的this被赋值为这个新对象(即this指向新对象);
  4. 执行构造函数内部的代码(给新对象添加属性);
  5. 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象;

一起来看看下面例子:

class Person {}

class Test1 {
    constructor () {
        console.log('Test1 初始化')
    }
}

class Test2 {
    constructor () {
        this.test = '通过初始化构造函数设置值'
    }
}

// 构造函数返回指定对象
const dataObj = { n: '自定义实例对象' }
class Test3 {
    constructor () {
        this.test = '通过初始化构造函数设置值'
        return dataObj
    }
}

const a = new Person();
const b = new Test1(); // Test1 初始化
const c = new Test2();
console.log(c.test) // 通过初始化构造函数设置值

const d = new Test3();
d instanceof Test3; // false
console.log(d) // { n: '自定义实例对象' }

类实例化时传入的参数会用作构造函数的参数。如果不需要参数,则类名后面的括号也是可选的:

class Person {
    constructor (...args) {
        console.log(args.length)
    }
}

class Test1 {
    constructor (test) {
        console.log(arguments.length)
        this.test = test || '默认值'
    }
}

// 不传值 可以省略()
const a = new Person // 0
const b = new Person('1', '2') // 2

const c = new Test1() // 0
console.log(c.test) // 默认值

const d = new Test1('传入值') // 1
console.log(d.test) // 传入值

const d = new Test1('1', '2', '3') // 3
console.log(d.test) // 1

与立即调用函数表达式相似,类也可以立即实例化:

const a = new class Person {
    constructor (text) {
        this.text = text
        console.log(text)
    }
}('立即实例化类');

// 立即实例化类

console.log(a); // Person

三、类的实例 、原型及类成员

类的语法可以非常方便地定义应该存在于实例上的成员、应该存在于原型上的成员,以及应该存在于类本身的成员。

实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上。

每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享:

class Person {
    constructor (x, y) {
        this.text = new Number(1);
        this.x = x
        this.y = y
        this.getText = () => {console.log(this.text)}
    }

    toString () {
        console.log(`${this.x}, ${this.y}`)
    }
}

const test1 = new Person('x', 'y'), test2 = new Person('x2', 'y2');

console.log(test1.getText()) // Number {1}
console.log(test2.getText()) // Number {1}
console.log(test1.x, test1.y) // x  y
console.log(test2.x, test2.y) // x2  y2

// console.log(test1.text === test2.text)  // false
// console.log(test1.getText === test2.getText)  // false

test1.text = '测试'

console.log(test1.getText()) // 测试
console.log(test2.getText()) // Number {1}

test1.toString() // x, y
test2.toString() // x2, y2

test1.hasOwnProperty('x'); // true
test1.hasOwnProperty('y'); // true
test1.hasOwnProperty('getText'); // true
test1.hasOwnProperty('toString'); // false
test1.__proto__.hasOwnProperty('toString'); // true

// 类的实例共享同一个原型对象
console.log(test1.__proto__ === test2.__proto__) // true

// 也可以使用ES6提供的 Object.getPrototypeOf 来获取prototype 
const test1Prototype = Object.getPrototypeOf(test1)
test1.myName = '共享字段'

// test2 中也是能获取到
console.log(test2.myName) // 共享字段

x、y、text和getText都是实例对象test1自身的属性,所以hasOwnProperty()方法返回true,而toString()是原型对象的属性(因为定义在Person类),所以hasOwnProperty()方法返回false,这些都与 ES5 的行为保持一致。

类的所有实例共享同一个原型对象。这也意味着,可以通过实例的__proto__属性或Object.getPrototypeOf方法获取原型为“类”添加方法,这将会出现共享情况,必须相当谨慎,不推荐使用,因为这会改变“类”的原始定义,影响到所有实例。

类方法等同于对象属性,因此可以使用字符串、符号或计算的值作为键:

const symbolKey = Symbol('test')

class Person {
    stringKey () {
        console.log('stringKey')
    }

    [symbolKey] () {
        console.log('symbolKey')
    }

    ['calculation' + '1'] () {
        console.log('calculation')
    }
}

const a = new Person();

a.stringKey() // stringKey
a[symbolKey]() // symbolKey
a.calculation1() // calculation

getter 与 setter 

在 class 内部可以使用 get set 关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

class Person {
    constructor (test) {
        this.test = test || '默认值'
    }

    get prop () {
        return this.test
    }

    set prop (value) {
        console.log(`setter prop value: ${value}`)
        this.test = value
    }
}

const p = new Person('1')

p.prop // 1

p.prop = '2' // setter prop value: 2

p.prop // 2

set函数和get函数是设置在属性的 Descriptor 对象上的,可以通过 Object.getOwnPrototyDescriptor 来获取指定属性的指定描述对象。

const descriptor = Object.getOwnPropertyDescriptor(Person.prototype, 'prop')

'get' in descriptor // true
'set' in descriptor // true

Generator 方法

如果某个方法之前加上星号(*),就表示该方法是一个 Generator 函数:

class Person {
  constructor(...args) {
    this.args = args;
  }
  * generatorFun () {
    for (let arg of this.args) {
      yield arg;
    }
  }
}

const a = new Person(1,2,3,4);
const generatorNext = a.generatorFun().next
generatorNext() // {value: 1, done: false}
generatorNext() // {value: 2, done: false}
generatorNext() // {value: 3, done: false}
generatorNext() // {value: 4, done: false}
generatorNext() // {value: undefined, done: true}

this 指向

类的方法内部如果含有this,它默认指向类的实例。但是某些情况是指向当前执行环境;

class Person {
    constructor () {
        this.text = '1'
    }

    getText () {
        console.log(this.text)
    }
}

const a = new Person()

a.getText() // 1

const {getText} = a

// this 指向为undefined class 默认严格模式
getText() // TypeError: Cannot read properties of undefined (reading 'text')

上面找不到 this 问题,this会指向该方法运行时所在的环境,因为 class 内部是严格模式,所以 this 实际指向的是undefined。有两个方法解决当前问题:

第一、构造方法中绑定this:

class Person {
    constructor() {
        this.text = '1'
        this.getText = this.getText.bind(this)
    }

    getText () {
        console.log(this.text)
    }
}

第二、使用箭头函数:

class Person {
    constructor() {
        this.text = '1'
    }

    getText = () => {
        console.log(this.text)
    }
}

箭头函数内部的 this 总是指向定义时所在的对象。

第三、使用proxy 在获取方法的时候自动绑定this:

function classProxy (target) {
    const map = new Map()
    
    // 读取拦截配置, 只需要配置 get
    const hanlder = {
        get(target, key) {
            const val = Reflect.get(target, key)
            // 要获取的是函数执行, 如果不是函数就直接返回 val
            if (typeof val !== 'function') return val

            if (!map.has(val)) {
                // 使用 bind改变运行函数的 this为拦截的实例对象
                map.set(val, val.bind(target))
            }
            return map.get(val)
        }
    }
    const proxy = new Proxy(target, hanlder)
    return proxy
}

class Person {
    constructor (text) {
        this.text = text
    }

    getText () {
        console.log(this.text)
        return this.text
    }
}

const person = classProxy(new Person('test'))

const { getText } = person

getText() // test

三、静态方法、静态属性及静态代码块

静态方法、静态属性及静态代码块(proposal-class-static-block)都是使用 static 关键字定义的属性、方法或块只能 class 自己用,不能通过实例继承。

静态方法中的this 指向的是 当前类,而不是指向实例对象。静态属性是当前类自身的属性。

class Person {
    static staticProp = 'Person静态属性'

    constructor () {
        // 通过 类名 获取
        console.log(`output: ${Person.staticProp}`)

        // 也可以通过 构造函数的属性
        this.constructor.staticFun1()
    }

    static staticFun1 () {
        this.staticFun2()
        console.log(`output: 静态方法staticFun1,获取Person静态属性 ==> ${Person.staticProp}`)
    }

    static staticFun2 () {
        console.log(`output: 静态方法staticFun2,获取静态属性 ==> ${this.staticProp}`)
    }
}

Person.staticProp // 静态属性

Person.staticFun1() 
// output: 静态方法staticFun2,获取静态属性 Person静态属性
// output: 静态方法staticFun1,获取Person静态属性 ==> Person静态属性

const a = new Person() // output: Person静态属性
a.staticProp // undefined
a.staticFun1 // undefined
a.staticFun2 // undefined
// 通过其原型构造函数还是能获取到 这些静态属性及方法 不推荐使用
// a.__proto__.constructor.staticProp
// a.__proto__.constructor.staticFun1()

静态代码块:

是在 Class 内创建了一个块状作用域,这个作用域内拥有访问 Class 内部私有变量的特权,在这个代码块内部,可以通过 this 访问 Class 所有成员变量,包括 # 私有变量,且这个块状作用域仅在引擎调用时初始化执行一次 ,决解以前初始化静态类属性需要设置一个静态变量初始化逻辑。

注意: static 变量或代码块都按顺序执行,父类优先执行,一个类中允许多个静态代码块存在。

class Person {
    static staticProp = '静态属性'
    static staticPropArr = []
    static staticPropObj = {}
    
    static getStatic (name) {
        console.log(`获取:${name}`, name && this[name])
        return name && this[name]
    }

    static resetData (name, data) {
        name && (this[name] = data)
        console.log(`重置:${name}`, name && this[name])
    }

    static {
        console.log('静态代码块执行');
        this.getStatic('staticProp');
        this.getStatic('staticPropArr');
        this.getStatic('staticPropObj');

        this.resetData('staticProp', '重置静态属性');
        this.resetData('staticPropArr', ['重置静态数组']);
        this.resetData('staticPropObj', { text: '重置静态对象' });

        this.staticPropObj.staticBlock1 = '代码块中直接设置'
        console.log(this.staticPropObj)
    }
}

/**
* 静态代码块执行
  获取:staticProp 静态属性
  获取:staticPropArr []
  获取:staticPropObj {}
  重置:staticProp 重置静态属性
  重置:staticPropArr ['重置静态数组']
  重置:staticPropObj {text: '重置静态对象'}
  {text: '重置静态对象', staticBlock1: '代码块中直接设置'}
*/

上面代码中可以看出,static 关键字后面不跟变量,而是直接跟一个代码块,就是 class static block 语法的特征,在这个代码块内部,可以通过 this 访问 Class 所有成员变量,包括 # 私有变量。

在这里提前使用一下私有变量,理论上 class 私有变量外部是访问不了的,但是有了静态代码块(class-static-block)之后,我们可以将私有属性暴露给外部变量:

let privateValue

export class Person {
  #value
  constructor(x) {
    this.#value = x
  }

  static {
    privateValue = (obj) => obj.#x;
  }
}

export function getPrivateValue (obj) {
  return privateValue(obj)
}


// 在另一个文件中 
import { Person, getPrivateValue } from 'xxx'

const a = new Person('私有变量')

getPrivateValue(a) // 私有变量

其实class-static-block本质上并没有增加新功能,我们完全可以用普通静态变量代替,只是写起来很不自然,所以这个特性可以理解为对缺陷的补充,或者是语法完善,个人认为现在越来越像java。

四、私有属性和私有方法

私有属性和私有方法,是只能在类的内部访问的方法和属性,外部不能访问,不可以直接通过 Class 实例来引用,其定义方式只需要在方法或属性前面添加 #

私有属性:

class Person {
    #privateVar1;
    #privateVar2 = '默认值';
    
    constructor (text) {
        this.#privateVar1 = text || '--'
        console.log(this.#privateVar1)
    }

    getPrivateData1 (key) {
        // 这里是获取不了的
        console.log('传入key来获取私有变量:', this[key])
        console.log('获取私有变量', this.#privateVar2, this.#privateVar1)
    }

    static staticGetPrivateData (person, key) {
        console.log('静态方法获取私有变量:', person.#privateVar2, person.#privateVar1)                     
        // 下面是获取不到
        console.log('静态方法传入key来获取私有变量:', person[key]) 
    }
}

const a = new Person() // 不传 默认 --
// output: --

a.getPrivateData1('#privateVar1')
// output: 传入key来获取私有变量:undefined
// output: 获取私有变量:  默认值  --

// 使用静态方法
Person.staticGetPrivateData(a, '#privateVar1')
// output: 静态方法获取私有变量:  默认值  --
// output: 静态方法传入key来获取私有变量:undefined

从上面代码中我们可以看到,私有变量是只能内部读取或写入,不能通过动态key读取(外部调用就会报错)

注意:在class 中 公共属性 test 与 #test 是两个完全不同的值;

私有方法:

class Person {
    #private;
    
    constructor () {
        this.#private = '私有变量'
        this.#methods() // 调用私有方法
    }

    #methods () {
        console.log('私有方法#methods:', this.#private)
    }

    static #staticMethods (person) {
        if (person) {
            console.log('静态私有方法#staticMethods person获取值', person.#private)
            person.#methods()
        }
    }

    init1 () {
        this.#methods()
        console.log('使用this')
        Person.#staticMethods(this)
    }

    init2 (person) {
        if (person) {
            console.log('使用传入实例')
            Person.#staticMethods(person)
        }
       
    }
}

const a = new Person()
// output: 私有方法#methods: 私有变量

// a.#methods()  SyntaxError
// a['#methods']()  TypeError: a.#methods is not a function

a.init1()
// output: 私有方法#methods: 私有变量
// output: 使用this
// output: 静态私有方法#staticMethods person获取值 私有变量
// output: 私有方法#methods: 私有变量

a.init2(a)
// output: 使用传入实例
// output: 静态私有方法#staticMethods person获取值 私有变量
// output: 私有方法#methods: 私有变量

从上面代码中我们可以看到,私有方法只能内部调用,在外部调用就会报错。

五、继承 extends

使用 extends 关键字,让子类继承父类的属性和方法。

class Person {
    num = 1
    text = 'person'

    getNum = () => console.log(this.num, this)

    addNum () {
        console.log(++this.num, this)
    }
}

// 继承
class Child extends Person {
    constructor () {
        super()
        this.getText()
    }

    getText = () => console.log(this.text, this)
}

const a = new Child() // output: person  Child {}

console.log(a instanceof Child) // output: true
console.log(a instanceof Person) // output: true

a.getText() // output: person Child {}
a.getNum() // output: 1 Child {}
a.addNum() // output: 2 Child {}
a.getNum() // output: 2 Child {}

a.text // person
a.num // 2

从上面代码中,我们可以看出Child 类 继承了 Person 的属性及方法,在Child 中也是可以调用Person的方法及属性,注意 this 的值会反映调用相应方法的实例或者类。子类中(Child)如果设置了 constructor 方法 就必须调用 super() ,否则就会出现新建实例时报错,如果没有 constructor 构造函数,在实例化继承类时会调用 super() ,而且会传入所有传给继承类的参数(后面会详细讲解)。

class Person {
    static staticText = 'staticText';
    #private = 'private'

    static staticMethods1 (person) {
        console.log('staticMethods1', this)
        person.#privateMethods()
    }

    #privateMethods () {
        console.log('#privateMethods', this)
    }
}

// 使用表达式格式 也是可以使用 extends 继承
const Child = class extends Person {
    methods () {
        console.log('methods', Child.staticText)
    }
}

const a = new Child()

a.methods() // output: methods staticText

Child.staticMethods1(a)
// output: staticMethods1  class Child {}
// output: #privateMethods Child {}

Person.staticMethods1(a)
// output: staticMethods1  class Person {}
// output: #privateMethods Child {}

使用表达式格式 也是可以使用 extends 继承,类 的静态方法与属性是可以继承的,其私有属性及方法是不能继承的,可以从继承的共有方法与静态方法 中获取其私有属性或调用其私有方法。

 super  关键字可以作函数使用,也可以作对象使用,但是其只能在继承类中使用,且只能在继承类的constructor 构造函数、实例方法和静态方法中使用。作为函数时是在 继承类的constructor 构造函数中使用,根据要求如果继承类中定义了constructor构造函数就必须要调用super方法(调用父类的constructor),否则就会报错。

class Person {}

class Child extends Person {
    constructor () {
        // 如果不调用 super() 就会报错
        // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor  
        super() // 调用父级的constructor
        console.log(this) // Child {}  
    }
}

注意: constructor() 中必须super() 顶部首段执行代码,否则也是一样报错;

在使用 super() 时应该注意下面几个问题:

  1. super只能在继承类构造函数和静态方法中使用。
    class Person {
        constructor () { 
            // 在非继承类 的constructor 中使用super 会报错
            super() //  SyntaxError: 'super' keyword unexpected here
        }
    
        methods () {
            console.log(super.text) // undefined
        }
    
        static staticMethods () {
            console.log(super.text) // undefined
        }
    }
  2.  不能单独引用super关键字,要么用它调用构造函数,要么用它引用静态方法。
    class Person {}
    
    class Child extends Person {
        
        constructor () {
            super // SyntaxError: 'super' keyword unexpected here
        }
    
        methods () {
            console.log(super) // SyntaxError: 'super' keyword unexpected here
        }
    
        static staticMethods () {
            console.log(super) // SyntaxError: 'super' keyword unexpected here
        }
    }
  3. 调用super()会调用父类构造函数,并将返回的实例赋值给this
    class Person {}
    class Child extends Person {
        constructor () {
            super()
            console.log(this instanceof Person) // output: true
        }
    }
    
    new Child()
  4. super() 的行为如同调用构造函数,如果需要给父类构造函数传参,则需要手动传入。
    class Person {
        constructor (text) {
            this.text = text
        }
    }
    
    class Child extends Person {
        constructor (text) {
            super(text)
        }
    }
    
    // 这里注意 其text 会设置到Child 中
    const a = new Child('设置 text') // Child { text: '设置 text' }
    
    console.log(a.text) // output: 设置 text
  5. 如果没有定义类构造函数,在实例化继承类时会调用super(),而且会传入所有传给继承类的参数。
    class Person {
        constructor (text) {
            this.text = text
        }
    }
    
    class Child extends Person {}
    
    const a = new Child('设置 text'); // Child { text: '设置 text' }
    
    // 上面提到过 会默认 生成 constructor (...arge) {super(...arge)}
  6. 在类构造函数中,不能在调用super()之前引用this,文章上面已经有案例及说明。
  7. 如果在继承类中显式定义了构造函数,则要么必须在其中调用super(),要么必须在其中返回一个对象。
    class Person {
        methods () {}
    }
    
    class Child1 extends Person {}
    
    class Child2 extends Person {
        constructor () {
            super()
        }
    }
    
    class Child3 extends Person {
        constructor () {
            return {}
        }
    }
    
    const a = new Child1() // Child1 {}
    
    const b = new Child2() // Child2 {}
    
    const c = new Child3() // {} 指向 实例函数 返回的对象 

    关于JS  Class 相关就介绍到这里,当然还有 Class的 mix-ins 混入及其他class相关知识,这边就不详细介绍了,有兴趣的同学可以自己去了解一下。

    文章内容参考了 《JavaScript高级程序设计》(第4版)https://book.douban.com/subject/35175321/

         掘金地址:
                JavaScript Class类详解 - 掘金

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37824255/article/details/124799714

智能推荐

证券公司信息化_什么是大数据?大数据在证券公司的应用怎样?数据价值发掘的陷阱有哪些?_为什么证券领域信息系统对存储数据量的要求较高-程序员宅基地

文章浏览阅读6.9k次。心血来潮搞24小时倒计时,把自己给逼住了。以后再不干这种傻事。花了几个小时,谈谈曾经有过的一些关于业务数据统计分析方面的感想。半年前从微博上看到大数据概念,想着跟数据仓库概念相近。查了百度百科,说是Internet留下的海量Text被人搞去非结构化分析。跟结构化的数据仓库相去甚远。但,就像“云计算”从最开始的Google的分布式数据处理的概念延伸到所有跟Internet服务端有_为什么证券领域信息系统对存储数据量的要求较高

python:实现将数据写入csv文件(附完整源码)_python写数据进本地csv文件-程序员宅基地

文章浏览阅读839次。python:实现将数据写入csv文件(附完整源码)_python写数据进本地csv文件

【3】C++语言代码---判断字符串是否是回文_c++判断回文字符串-程序员宅基地

文章浏览阅读4k次,点赞5次,收藏25次。判断字符串是否是回文?思路一: 直接通过循环i(循环字符串长度的一半次),比较第一个字符和最后一个字符是否相同,第二个字符和倒数第二个字符是否相同,直到循环结束。即比较 a[i] = a[len - 1 - i] (i=0;i_c++判断回文字符串

毕设分享 基于STM32的六臂行走机器小车设计(源码+论文)-程序员宅基地

文章浏览阅读384次,点赞12次,收藏6次。本设计主要是基于单片机的六足机器人控制系统设计,综合分析六足机器人的结构、步态和控制算法,结合云端服务器、WIFI技术、蓝牙技术、语音识别技术和手势识别技术进行多种控制模式的设计,并提出不同应用场景的不同构建方案。接口电路设计—WIFI模块接口电路设计—蓝牙模块接口电路设计—语音模块接口电路设计—手势模块。

Android MultiDex-程序员宅基地

文章浏览阅读51次。出现的原因:Android 5.0 之前版本的 Dalvik 可执行文件分包支持Android 5.0(API 级别 21)之前的平台版本使用 Dalvik 运行时来执行应用代码。默认情况下,Dalvik 限制应用的每个 APK 只能使用单个classes.dex字节码文件。要想绕过这一限制,您可以使用MultiDex,它会成为您的应用主要 DEX 文件的一部分,然后管理对其他 DE...

随便推点

京东商城京东白条使用详解 图解京东白条的使用方法-程序员宅基地

文章浏览阅读3.7k次。京东商城京东白条使用详解,最近京东推出的京东白条服务,非常不错,目前正在内测中,也有部分用户被邀请京东白条的测试了。就京东白条的使用,小编请有资格付款的朋友帮接截了点图,各位可以看一下。1、首先如果你是有资格内测京东白条的用户,在登录京东商城以后,点击“我的订单-账户中心-京东白条”,如图所示:

python抢演唱会门票_韩国演唱会抢票系统生产环境(Linux)配置记录-程序员宅基地

文章浏览阅读773次。韩国演唱会抢票系统生产环境:系统:CentOS Linux release 7.2.1511 (Core)Linux管理系统:宝塔 (免费版 7.0.3)开发语言:NodeJS (v12.14.0)NodeJS开发框架:ThinkJS其它说明:本系统是可以在远程主机中使用,也可以在本地搭建环境使用。windows系统/Liunx系统 都可以。流程:1、购买服务器及域名对于抢购秒杀类系统,服务器核心...

记事本写的python怎么运行_如何在记事本++中执行Python文件?-程序员宅基地

文章浏览阅读1.5k次。第一种选择:(最简单,推荐)打开记事本++。在菜单上转到:运行->运行。(F5)。输入:C:\Python26\python.exe "$(FULL_CURRENT_PATH)"现在,不用按运行,而是按保存为其创建快捷方式。笔记如果您拥有Python 3.1:请输入Python31而不是Python26-i如果希望脚本完成后命令行窗口保持打开状态,请添加第二选择使用运行Python脚本的批处理脚本..._怎么用记事本写python代码并运行

【爬虫实战】Python 自制天气预报程序!爬取全国天气网_python 天气预报 requests pxquery xlwt-程序员宅基地

文章浏览阅读6.2k次,点赞23次,收藏119次。用 requests 爬取全国天气网的网页源代码;用 pyquery 解析网页源代码,取得天气情况信息的节点;用 xlwt 将信息保存到本地 Excel 文件。_python 天气预报 requests pxquery xlwt

VB 卸载USB设备/解锁文件_vb 退出 弹出 u盘-程序员宅基地

文章浏览阅读1.3w次,点赞2次,收藏8次。这次索性贴完整源码,希望能对大家有所帮助.frmMain.frmVERSION 5.00Begin VB.Form frmMain BorderStyle = 1 Fixed Single Caption = "Usb卸载程序" ClientHeight = 2445 ClientLeft = 45 Clie_vb 退出 弹出 u盘

HbuilderX运行打包项目时报node.exe: --openssl-legacy-provider is not allowed in NODE_OPTIONS的解决办法_hbuilderx\plugins\node\node.exe: --openssl-legacy--程序员宅基地

文章浏览阅读1.3w次,点赞8次,收藏10次。发现是可以打印出这个系统环境变量的,那就想办法把这个变量删除掉,可是想尽了办法也删不掉这个环境变量。在我的电脑—>右键属性–>高级系统设置—>环境变量,确实也没有这个变量了。最后还是新建了一个空的NODE_OPTIONS环境变量。最后把hbuilderx换成历史的版本同样存在此问题。后来记得原来在系统环境变量配置中经加过,系统环境变量。更新到v3.6.7 ALPHA版本也照常存在此错误。一直以为是版本的问题,把hbuilderx更换到。最新的正式版v3.6.4 此问题照常存在。_hbuilderx\plugins\node\node.exe: --openssl-legacy-provider is not allowed in

推荐文章

热门文章

相关标签