当前位置: 首页 > news >正文

ES6基础3

  1. 函数的扩展
    1. 基本用法
      1. 函数参数的默认值
        ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
      2. 参数变量是默认声明的,所以不能用letconst再次声明。下面代码中,参数变量x是默认声明的,在函数体中,不能用letconst再次声明,否则会报错。
        function foo(x = 5) {let x = 1; // errorconst x = 2; // error
        }
    2. 与解构赋值默认值结合使用
      1. 参数默认值可以与解构赋值的默认值,结合起来使用。下面代码使用了对象的解构赋值默认值,而没有使用函数参数的默认值。只有当函数foo的参数是一个对象时,变量xy才会通过解构赋值而生成。如果函数foo调用时参数不是对象,变量xy就不会生成,从而报错。如果参数对象没有y属性,y的默认值5才会生效。
        function foo({x, y = 5}) {console.log(x, y);
        }foo({}) // undefined, 5
        foo({x: 1}) // 1, 5
        foo({x: 1, y: 2}) // 1, 2
        foo() // TypeError: Cannot read property 'x' of undefined

        下面两种写法都对函数的参数设定了默认值,区别是写法一函数参数默认值空对象,但是设置对象解构赋值的默认值;写法二函数参数默认值是一个有具体属性对象,但是没有设置对象解构赋值默认值

        // 写法一
        function m1({x = 0, y = 0} = {}) {return [x, y];
        }// 写法二
        function m2({x, y} = { x: 0, y: 0 }) {return [x, y];
        }
        值。// 函数没有参数的情况
        m1() // [0, 0]
        m2() // [0, 0]// x和y都有值的情况
        m1({x: 3, y: 8}) // [3, 8]
        m2({x: 3, y: 8}) // [3, 8]// x有值,y无值的情况
        m1({x: 3}) // [3, 0]
        m2({x: 3}) // [3, undefined]// x和y都无值的情况
        m1({}) // [0, 0];
        m2({}) // [undefined, undefined]m1({z: 3}) // [0, 0]
        m2({z: 3}) // [undefined, undefined]

        个人理解当m1没有传入参数时,参数设置为空对象,使用对象结构值为{x = 0, y = 0};当m2没有传入参数时,使用设置的默认参数

    3. 参数默认值的位置
      1. 通常情况下,定义默认值参数应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数。如果非尾部参数设置默认值,实际上这个参数是没法省略的。
        // 例一
        function f(x = 1, y) {return [x, y];
        }f() // [1, undefined]
        f(2) // [2, undefined])
        f(, 1) // 报错
        f(undefined, 1) // [1, 1]// 例二
        function f(x, y = 5, z) {return [x, y, z];
        }f() // [undefined, 5, undefined]
        f(1) // [1, 5, undefined]
        f(1, ,2) // 报错
        f(1, undefined, 2) // [1, 5, 2]
      2. 如果传入undefined,将触发该参数等于默认值null没有这个效果
        function foo(x = 5, y = 6) {console.log(x, y);
        }foo(undefined, null)
        // 5 null
    4. 函数的length属性
      1. 指定默认值以后,函数的length属性,将返回没有指定默认值参数个数。也就是说,指定了默认值后,length属性将失真。
        (function (a) {}).length // 1
        (function (a = 5) {}).length // 0
        (function (a, b, c = 5) {}).length // 2
      2. 因为length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。同理,rest参数不会计入length属性
        (function(...args) {}).length // 0
      3. 如果设置了默认值参数不是尾参数,那么length属性不再计入后面的参数了。
        (function (a = 0, b, c) {}).length // 0
        (function (a, b = 1, c) {}).length // 1
    5. 作用域
      1. 下面代码中,函数foo的参数x的默认值也是x。这时,默认值x的作用域是函数作用域,而不是全局作用域。由于在函数作用域中,存在变量x,但是默认值在x赋值之前先执行了,所以这时属于暂时性死区(参见《let和const命令》一章),任何对x的操作都会报错。
        var x = 1;function foo(x = x) {// ...
        }foo() // ReferenceError: x is not defined

    6. 应用
      1. 利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
        function throwIfMissing() {throw new Error('Missing parameter');
        }function foo(mustBeProvided = throwIfMissing()) {return mustBeProvided;
        }foo()
        // Error: Missing parameter

        上面代码的foo函数,如果调用的时候没有参数,就会调用默认值throwIfMissing函数,从而抛出一个错误。

        从上面代码还可以看到,参数mustBeProvided的默认值等于throwIfMissing函数的运行结果(即函数名之后有一对圆括号),这表明参数的默认值不是在定义时执行,而是在运行时执行(即如果参数已经赋值,默认值中的函数就不会运行),这与python语言不一样。

        另外,可以将参数默认值设为undefined,表明这个参数是可以省略的。

        function foo(optional = undefined) { ··· }
    7. rest参数
      1. ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中
        function add(...values) {let sum = 0;for (var val of values) {sum += val;}return sum;
        }add(2, 5, 3) // 10
      2. 注意,rest参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
        // 报错
        function f(a, ...b, c) {// ...
        }
      3. 函数的length属性不包括rest参数
        (function(a) {}).length  // 1
        (function(...a) {}).length  // 0
        (function(a, ...b) {}).length  // 1
    8. 扩展运算符
      1. 扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算一个数组转为用逗号分隔的参数序列
        console.log(...[1, 2, 3])
        // 1 2 3console.log(1, ...[2, 3, 4], 5)
        // 1 2 3 4 5[...document.querySelectorAll('div')]
        // [<div>, <div>, <div>]
      2. 该运算符主要用于函数调用。
        function push(array, ...items) {array.push(...items);
        }function add(x, y) {return x + y;
        }var numbers = [4, 38];
        add(...numbers) // 42

        上面代码中,array.push(...items)add(...numbers)这两行,都是函数的调用,它们的都使用了扩展运算符。该运算符将一个数组,变为参数序列。

      3. 扩展运算符与正常的函数参数可以结合使用,非常灵活。
        function f(v, w, x, y, z) { }
        var args = [0, 1];
        f(-1, ...args, 2, ...[3]);
    9. 扩展运算符的应用
      1. 合并数组:扩展运算符提供了数组合并的新写法。
        // ES5
        [1, 2].concat(more)
        // ES6
        [1, 2, ...more]var arr1 = ['a', 'b'];
        var arr2 = ['c'];
        var arr3 = ['d', 'e'];// ES5的合并数组
        arr1.concat(arr2, arr3);
        // [ 'a', 'b', 'c', 'd', 'e' ]// ES6的合并数组
        [...arr1, ...arr2, ...arr3]
        // [ 'a', 'b', 'c', 'd', 'e' ]

      2. 与解构赋值结合:扩展运算符可以与解构赋值结合起来,用于生成数组
        // ES5
        a = list[0], rest = list.slice(1)
        // ES6
        [a, ...rest] = list

        下面是另外一些例子。

        const [first, ...rest] = [1, 2, 3, 4, 5];
        first // 1
        rest  // [2, 3, 4, 5]const [first, ...rest] = [];
        first // undefined
        rest  // []:const [first, ...rest] = ["foo"];
        first  // "foo"
        rest   // []

        如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

        const [...butLast, last] = [1, 2, 3, 4, 5];
        // 报错const [first, ...middle, last] = [1, 2, 3, 4, 5];
        // 报错
      3. 字符串

        1. 扩展运算符还可以将字符串转为真正的数组。

          [...'hello']
          // [ "h", "e", "l", "l", "o" ]
        2. 正确返回字符串长度的函数,可以像下面这样写。

          function length(str) {return [...str].length;
          }
          
      4. 实现了Iterator接口的对象
        1. 任何Iterator接口的对象,都可以用扩展运算符转为真正的数组。下面是一个最特殊的例子。它不是数组,而一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了Iterator接口
          var nodeList = document.querySelectorAll('div');
          var array = [...nodeList];
        2. 对于那些没有部署Iterator接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。下面代码中,arrayLike是一个类似数组的对象,但是没有部署Iterator接口,扩展运算符就会报错。这时,可以改为使用Array.from方法将arrayLike转为真正的数组。
          let arrayLike = {'0': 'a','1': 'b','2': 'c',length: 3
          };// TypeError: Cannot spread non-iterable object.
          let arr = [...arrayLike];
    10. Map和Set结构,Generator函数
      1. 扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。
        let map = new Map([[1, 'one'],[2, 'two'],[3, 'three'],
        ]);let arr = [...map.keys()]; // [1, 2, 3]
      2. Generator函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。
        var go = function*(){yield 1;yield 2;yield 3;
        };[...go()] // [1, 2, 3]

        下面代码中,变量go是一个Generator函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。

        如果对没有iterator接口的对象,使用扩展运算符,将会报错。

        var obj = {a: 1, b: 2};
        let arr = [...obj]; // TypeError: Cannot spread non-iterable object
    11. name属性
      1. 函数的name属性,返回该函数的函数名。
        function foo() {}
        foo.name // "foo"
        var func1 = function () {};// ES5
        func1.name // ""// ES6
        func1.name // "func1"
        const bar = function baz() {};// ES5
        bar.name // "baz"// ES6
        bar.name // "baz"

    12. 箭头函数
      1. 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
  2. 对象的扩展
    1. 属性的简洁表示法
      1. ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。下面代码表明,ES6允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。下面是另一个例子。
    2. 属性名表达式
      1. ES6 允许字面量定义对象时,用(表达式)作为对象的属性名,即把表达式放在方括号内。
        let propKey = 'foo';let obj = {[propKey]: true,['a' + 'bc']: 123
        };
      2. 注意,属性名表达式简洁表示法不能同时使用,会报错。
        // 报错
        var foo = 'bar';
        var bar = 'abc';
        var baz = { [foo] };// 正确
        var foo = 'bar';
        var baz = { [foo]: 'abc'};
      3. 注意,属性名表达式如果一个对象默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。下面代码中,[keyA][keyB]得到的都是[object Object],所以[keyB]会把[keyA]覆盖掉,而myObject最后只有一个[object Object]属性。
        const keyA = {a: 1};
        const keyB = {b: 2};const myObject = {[keyA]: 'valueA',[keyB]: 'valueB'
        };myObject // Object {[object Object]: "valueB"}
    3. Object.is()
      1. ES5比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。ES6提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
        Object.is('foo', 'foo')
        // true
        Object.is({}, {})
        // false//不同之处只有两个:一是+0不等于-0,二是NaN等于自身。+0 === -0 //true
        NaN === NaN // falseObject.is(+0, -0) // false
        Object.is(NaN, NaN) // true
    4. Object.assign()
      1. Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性复制到目标对象(target)。Object.assign方法的第一个参数是目标对象后面的参数都是源对象。注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性覆盖前面属性。如果只有一个参数,Object.assign会直接返回该参数。如果该参数不是对象,则会先转成对象然后返回。由于undefinednull无法转成对象,所以如果它们作为参数(仅限第一个参数),就会报错(其它参数无法转成对象,会直接跳过)。
        var target = { a: 1 };var source1 = { b: 2 };
        var source2 = { c: 3 };Object.assign(target, source1, source2);
        target // {a:1, b:2, c:3}
      2. 其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
        var v1 = 'abc';
        var v2 = true;
        var v3 = 10;var obj = Object.assign({}, v1, v2, v3);
        console.log(obj); // { "0": "a", "1": "b", "2": "c" }
      3. 注意点:
        1. Object.assign方法实行的是浅拷贝,而不是深拷贝。深拷贝实现方式如下
           Object.assign(obj2,JSON.parse(JSON.stringify(obj1)))
        2. 常见用途
          1. 为对象添加属性
            class Point {constructor(x, y) {Object.assign(this, {x, y});}
            }
          2. 为对象添加方法
            Object.assign(SomeClass.prototype, {someMethod(arg1, arg2) {···},anotherMethod() {···}
            });// 等同于下面的写法
            SomeClass.prototype.someMethod = function (arg1, arg2) {···
            };
            SomeClass.prototype.anotherMethod = function () {···
            };
          3. 克隆对象
            function clone(origin) {return Object.assign({}, origin);
            }
          4. 合并多个对象
            const merge =(target, ...sources) => Object.assign(target, ...sources);
          5. 为属性指定默认值
            const DEFAULTS = {logLevel: 0,outputFormat: 'html'
            };function processContent(options) {options = Object.assign({}, DEFAULTS, options);
            }
    5. 属性的可枚举性
      1. 对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取属性描述对象
        let obj = { foo: 123 };
        Object.getOwnPropertyDescriptor(obj, 'foo')
        //  {
        //    value: 123,
        //    writable: true,
        //    enumerable: true,
        //    configurable: true
        //  }
      2. 描述对象的enumerable属性,称为”可枚举性“,如果该属性为false,就表示某些操作忽略当前属性。ES5有三个操作会忽略enumerable为false的属性。

        for...in循环:只遍历对象自身的和继承的可枚举的属性
        Object.keys():返回对象自身的所有可枚举的属性的键名
        JSON.stringify():只串行化对象自身的可枚举的属性
        ES6新增了一个操作Object.assign(),会忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

        这四个操作之中,只有for...in会返回继承的属性。实际上,引入enumerable的最初目的,就是让某些属性可以规避掉for...in操作比如,对象原型的toString方法,以及数组的length属性,就通过这种手段,不会被for...in遍历到。

        Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
        // falseObject.getOwnPropertyDescriptor([], 'length').enumerable
        // false
      3. 上面代码中,toStringlength属性的enumerable都是false,因此for...in不会遍历到这两个继承自原型的属性。另外,ES6规定,所有Class的原型的方法都是不可枚举的。

        Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, 'foo').enumerable
        // false
      4. 总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用for...in循环,而使用Object.keys()代替

    6. __proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()
      1. __proto__属性
        1. __proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括IE11)都部署了这个属性。
          // es6的写法
          var obj = {method: function() { ... }
          };
          obj.__proto__ = someOtherObj;// es5的写法
          var obj = Object.create(someOtherObj);
          obj.method = function() { ... };
        2. 该属性没有写入ES6的正文,而是写入了附录,原因__proto__前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的API,只是由于浏览器广泛支持,才被加入了ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。
      2. Object.setPrototypeOf()
        1. Object.setPrototypeOf方法的作用与__proto__相同,用来设置一个对象的prototype对象。它是ES6正式推荐的设置原型对象的方法。
          // 格式
          Object.setPrototypeOf(object, prototype)// 用法
          var o = Object.setPrototypeOf({}, null);
        2. 该方法等同于下面的函数。
          function (obj, proto) {obj.__proto__ = proto;return obj;
          }
        3. 下面是一个例子。
          let proto = {};
          let obj = { x: 10 };
          Object.setPrototypeOf(obj, proto);proto.y = 20;
          proto.z = 40;obj.x // 10
          obj.y // 20
          obj.z // 40

          上面代码将proto对象设为obj对象的原型,所以从obj对象可以读取proto对象的属性。

      3. Object.getPrototypeOf()
        1. 该方法与setPrototypeOf方法配套,用于读取一个对象的prototype对象
          Object.getPrototypeOf(obj);
        2. 下面是一个例子。
          function Rectangle() {
          }var rec = new Rectangle();Object.getPrototypeOf(rec) === Rectangle.prototype
          // trueObject.setPrototypeOf(rec, Object.prototype);
          Object.getPrototypeOf(rec) === Rectangle.prototype
          // false
    7. Object.values()
      1. Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
        var obj = { foo: "bar", baz: 42 };
        Object.values(obj)
        // ["bar", 42]
      2. 返回数组的成员顺序,与《属性的遍历》介绍的排列规则一致。(首先遍历所有属性名为数值的属性,按照数字排序其次遍历所有属性名为字符串的属性,按照生成时间排序最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
        var obj = { 100: 'a', 2: 'b', 7: 'c' };
        Object.values(obj)
        // ["b", "c", "a"]
      3. 上面代码中,属性名为数值的属性,是按照数值大小,从小到大遍历的,因此返回的顺序是bcaObject.values只返回对象自身的可遍历属性。

        var obj = Object.create({}, {p: {value: 42}});
        Object.values(obj) // []
      4. 上面代码中,Object.create方法的第二个参数添加的对象属性(属性p),如果不显式声明,默认是不可遍历的。Object.values不会返回这个属性。Object.values会过滤属性名为Symbol值的属性。

        Object.values({ [Symbol()]: 123, foo: 'abc' });
        // ['abc']
      5. 如果Object.values方法的参数是一个字符串,会返回各个字符组成的一个数组。

        Object.values('foo')
        // ['f', 'o', 'o']
      6. 上面代码中,字符串会先转成一个类似数组的对象。字符串的每个字符,就是该对象的一个属性。因此,Object.values返回每个属性的键值,就是各个字符组成的一个数组。

        如果参数不是对象,Object.values会先将其转为对象。由于数值和布尔值的包装对象,都不会为实例添加非继承的属性。所以,Object.values会返回空数组。

        Object.values(42) // []
        Object.values(true) // []
    8. Object.entries()
      1. Object.entries方法返回一个数组成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组
        var obj = { foo: 'bar', baz: 42 };
        Object.entries(obj)
        // [ ["foo", "bar"], ["baz", 42] ]
      2. 除了返回值不一样,该方法的行为与Object.values基本一致。如果原对象的属性名是一个Symbol值,该属性会被省略。

    9. 对象的扩展运算符
      1. 解构赋值
        1. 对象的解构赋值用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。
          let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
          x // 1
          y // 2
          z // { a: 3, b: 4 }

        2. 扩展运算符
          1. 扩展运算符(...)用于取出参数对象所有可遍历属性拷贝到当前对象之中
            let z = { a: 3, b: 4 };
            let n = { ...z };
            n // { a: 3, b: 4 }
          2. 扩展运算符可以用于合并两个对象。
            let ab = { ...a, ...b };
            // 等同于
            let ab = Object.assign({}, a, b);
    10. Object.getOwnPropertyDescriptors()
      1. ES7有一个提案,提出了Object.getOwnPropertyDescriptors方法,返回指定对象所有自身属性(非继承属性)的描述对象。
        const obj = {foo: 123,get bar() { return 'abc' }
        };Object.getOwnPropertyDescriptors(obj)
        // { foo:
        //    { value: 123,
        //      writable: true,
        //      enumerable: true,
        //      configurable: true },
        //   bar:
        //    { get: [Function: bar],
        //      set: undefined,
        //      enumerable: true,
        //      configurable: true } }

        Object.getOwnPropertyDescriptors方法返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。

相关文章:

ES6基础3

函数的扩展 基本用法 函数参数的默认值 ES6允许为函数的参数设置默认值&#xff0c;即直接写在参数定义的后面。 参数变量是默认声明的&#xff0c;所以不能用let或const再次声明。下面代码中&#xff0c;参数变量x是默认声明的&#xff0c;在函数体中&#xff0c;不能用let或c…...

HarmonyOS 数据持久化 关系型数据库之 初始化操作

上文 HarmonyOS 数据持久化之首选项 preferences 我们有说用户首选项 但它只能处理一些比较简单的数据类型结构 的持久化处理 如果是一些批量较大 结构较为复杂的数据结构 那么 首选项就无法满足了 我们就要选择 关系型数据库 通过 SQLite 组件实现的一种本地数据库&#xff0…...

伊芙丽签约实在智能,实在Agent数字员工助力品牌效能飙升

近日&#xff0c;国内知名时尚女装品牌伊芙丽与实在智能达成合作&#xff0c;引入业内领先的平台级自动化产品实在Agent数字员工——取数宝&#xff0c;自动获取天猫、淘宝、抖音等线上平台营销数据&#xff0c;开启全域化营销的“提效之旅”。 实在Agent智能体 伊芙丽集团成立…...

第十五届蓝桥杯-UART接收不定长指令的处理

学习初衷&#xff1a; 不仅仅为了比赛&#xff01; 目录 一、问题引入 二、UART常用的三种工作模式 1.UART工作在中断模式 2.UART工作在DMA模式下 3.uart工作在接收转空闲的模式下 三、获取指令中需要的数据 四、printf函数的实现 一、问题引入 问题引入&#xff1a;请…...

网络 协议 UDP编程

网络:数据传输,数据共享 1.网络协议模型: OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#xff09…...

3505. 这也是一道排序题

一、题目 输入 10 7334774857 8461862436 540886577 5245195052 9194400521 5412986878 6694133363 1186771950 1405713915 7115286932 输出 -29430338967 二、思考 构造差分数组&#xff1a;C[i] A[i1] - A[i] 由题目条件可知&#xff1a;当A[i] A[i1] A[i-1] - A[i]时&am…...

【Redis】Redis的应用场景

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Redis ⛺️稳中求进&#xff0c;晒太阳 Redis的应用场景&#xff1a; 限流 要求10s内只能访问一次 RequestMapping("xian")public String xianLiu(String sign){String sign1 …...

计算机网络—以太网接口和链路配置

目录 1.拓扑图 2.以太网交换机基础配置 3.配置手动模式的链路聚合 4.配置静态 LACP 模式的链路聚合 5.配置文件 1.拓扑图 2.以太网交换机基础配置 华为交换机接口默认开启了自协商功能&#xff0c;需要手动配置S1与 S2上G0/0/9和G0/0/10接口的速率。 首先修改交换机的设…...

关于做副业、做自媒体:说几句扎心的话

今天在某乎看到一个问题&#xff1a;想尝试自媒体&#xff0c;想了一个月了&#xff0c;都没想好怎么起步&#xff0c;咋整呀&#xff1f; 恰好昨天陪退休老妈去探店&#xff0c;有感而发&#xff0c;就来唠一唠。 一、退休老妈的副业经历 老妈去年年初开始&#xff0c;在某…...

精通SpringBoot单元测试

引言 单元测试是软件开发中不可或缺的一部分&#xff0c;它对保障代码质量和软件的可靠性起着至关重要的作用。而SpringBoot作为一个流行的Java框架&#xff0c;为开发高效、易于部署的微服务提供了强大的支持。 单元测试的重要性&#xff1a; 确保代码正确性&#xff1a;通过…...

HAProxy 简单介绍

一 HAProxy介绍 &#xff08;一&#xff09;发展历史 HAProxy是法国开发者威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件&#xff0c;是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器&#xff0c;支持基于cookie的持久性&#xff0c;自动故障切换…...

SpringBoot集成Swagger3.0

一&#xff1a;前言   Swagger 是一个 RESTful API 的开源框架&#xff0c;它的主要目的是帮助开发者设计、构建、文档化和测试 Web API。Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式&#xff0c;以提高 API 的可读性、可靠性和易用性&#xff0c;同时降…...

计算机网络-第5章 运输层(1)

主要内容&#xff1a;进程之间的通信与端口、UDP协议、TCP协议、可靠传输原理&#xff08;停止等待协议、ARQ协议&#xff09;、TCP报文首部、TCP三大题&#xff1a;滑动窗口、流量控制、拥塞控制机制 5.1 运输层协议概述 运输层向它上面的应用层提供通信服务&#xff0c;真正…...

性能优化-卡牌项目渲染优化

优化的方向 CPU 影响帧率 GPU 影响帧率 内存 超了会崩 显存 显存超了画面会异常&#xff0c;甚至可能导致游戏崩溃 带宽 影响耗电 分辨率 设备性能不行又要求流畅&#xff0c;降低目标渲染分辨率&#xff0c;立竿见影&#xff0c;但是会牺牲画质 场景 1 使用烘焙…...

STM32FreeRTOS任务通知(STM32cube高效开发)

文章目录 一、任务通知(一&#xff09;任务通知概述1、任务通知可模拟队列和信号量2、任务通知优势和局限性 (二) 任务通知函数1、xTaskNotify&#xff08;&#xff09;发送通知值不返回先前通知值的函数2、xTaskNotifyFromISR&#xff08;&#xff09;发送通知函数ISR版本3、x…...

基于element-plus的Dialog选择控件

翻看之前工程师写的vue2的代码&#xff0c;很多都是复制、粘贴&#xff0c;也真是搞不懂&#xff0c;明明可以写一个控件&#xff0c;不就可以重复使用。很多前端总喜欢element搞一下&#xff0c;ant-design也搞一下&#xff0c;有啥意义&#xff0c;控件也不是自己写的&#x…...

手把手教使用静默 搭建Oracle 19c 一主一备ADG集群

一、环境搭建 主机IPora19192.168.134.239ora19std192.168.134.240 1.配置yum源 1.配置网络yum源 1.删除redhat7.0系统自带的yum软件包&#xff1b; rpm -qa|grep yum >oldyum.pkg 备份原信息rpm -qa|grep yum|xargs rpm -e --nodeps 不检查依赖&#xff0c;直接删除…...

使用协程库httpx并发请求

httpx和aiohttp都是比较常用的异步请求库&#xff0c;当然requests多线程或requestsgevent也是不错的选择。 一个使用httpx进行并发请求的脚本如下&#xff1a; import functools import sys import timeimport anyio import httpxasync def fetch(client, results, index) -…...

js的同步异步

JavaScript&#xff08;JS&#xff09;是一门单线程的编程语言&#xff0c;这意味着它一次只能处理一个任务。然而&#xff0c;JS 支持同步和异步操作。 同步操作是指代码按照顺序执行&#xff0c;每个操作必须在前一个操作完成后才能进行。这意味着当一个操作在执行时&#x…...

C# MG.CamCtrl 工业相机库(开源) 海康 大恒

C# MG.CamCtrl 相机库&#xff08;开源&#xff09; 海康 大恒 介绍工厂模式创建实例选取对应SN号的相机&#xff0c;初始化启动相机取图注销相机参数设置/获取接口 介绍 c# 相机库&#xff0c;含海康、大恒品牌2D相机的常用功能。 底层采用回调信号量模式封装 &#xff0c;最…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...