主頁 > 後端開發 > ES 新特性與 TypeScript、JS 性能優化(Day06)

ES 新特性與 TypeScript、JS 性能優化(Day06)

2020-11-06 12:32:21 後端開發

Part1 · JavaScript【深度剖析】

ES 新特性與 TypeScript、JS 性能優化

文章說明:本專欄內容為本人參加【拉鉤大前端高新訓練營】的學習筆記以及思考總結,學徒之心,僅為分享,如若有誤,請在評論區支出,如果您覺得專欄內容還不錯,請點贊、關注、評論,

共同進步!

上一篇:【ECMAScript概述】、【ES6概述】、【var let const】、【陣列與物件的解構】

今天內容有點多,不過大多數都是API用法,只是比較細碎,慢慢嚼,多使用,在使用的程序中加深理解,

七、ES2015模板字串

1.模板字面量

ECMAScript 6 新增了使用模板字面量定義字串的能力,與使用單引號或雙引號不同,模板字面量保留換行字符,可以跨行定義字串:

使用鍵盤區域Esc下方【數字1左邊】的反引號

let myMultiLineString = 'first line\nsecond line'; 
let myMultiLineTemplateLiteral = `first line 
second line`; 
console.log(myMultiLineString); 
// first line 
// second line" 
console.log(myMultiLineTemplateLiteral); 
// first line
// second line
console.log(myMultiLineString === myMultiLinetemplateLiteral); // true

所以說,當我們需要寫HTML模板時,這個方法非常有用:

let pageHTML = ` 
<div> 
 <a href="#"> 
 <span>Jake</span> 
 </a> 
</div>`;

由于模板字面量會保持反引號內部的空格,因此在使用時要格外注意,格式正確的模板字串看起來可能會縮進不當,

2.字串插值

模板字面量最常用的一個特性是支持字串插值,也就是可以在一個連續定義中插入一個或多個值,技術上講,**模板字面量不是字串,而是一種特殊的 JavaScript 句法運算式,只不過求值后得到的是字串,**模板字面量在定義時立即求值并轉換為字串實體,任何插入的變數也會從它們最接近的作用域中取值,

字串插值通過在${}中使用一個 JavaScript 運算式實作:

let value = 5; 
let exponent = 'second'; 
// 以前,字串插值是這樣實作的:
let interpolatedString = value + ' to the ' + exponent + ' power is ' + (value * value); 
// 現在,可以用模板字面量這樣實作:
let interpolatedTemplateLiteral = `${ value } to the ${ exponent } power is ${ value * value }`; 
console.log(interpolatedString); // 5 to the second power is 25 
console.log(interpolatedTemplateLiteral); // 5 to the second power is 25
// 所有插入的值都會使用 toString()強制轉型為字串,而且任何 JavaScript 運算式都可以用于插值,

3.模板字面量標簽函式

模板字面量也支持定義標簽函式(tag function),而通過標簽函式可以自定義插值行為,標簽函式會接收被插值記號分隔后的模板對每個運算式求值的結果

標簽函式本身是一個常規函式,通過前綴到模板字面量來應用自定義行為,如下例所示,標簽函式接收到的引數依次是原始字串陣列和對每個運算式求值的結果,這個函式的回傳值是對模板字面量求值得到的字串,

這樣概念解釋很不清楚,通過下方的例子來加強理解:

let a = 6; 
let b = 9; 
function simpleTag(strings, ...expressions) { 
 	console.log(strings); 
 	for(const expression of expressions) { 
 		console.log(expression); 
 	} 
 	return 'foobar'; 
} 
let taggedResult = simpleTag`${ a } + ${ b } = ${ a + b }`; 
// ["", " + ", " = ", ""] 
// 6 
// 9 
// 15 
console.log(taggedResult); // "foobar"

八、ES2015引數默認值

在 ECMAScript5.1 及以前,實作默認引數的一種常用方式就是檢測某個引數是否等于 undefined,如果是則意味著沒有傳這個引數,那就給它賦一個值:

function makeKing(name) { 
     name = (typeof name !== 'undefined') ? name : 'Henry'; 
     return `King ${name} VIII`; 
} 
console.log(makeKing()); // 'King Henry VIII' 
console.log(makeKing('Louis')); // 'King Louis VIII'

ECMAScript 6 之后就不用這么麻煩了,因為它支持顯式定義默認引數了,下面就是與前面代碼等價的 ES6 寫法,只要在函式定義中的引數后面用=就可以為引數賦一個默認值:

function makeKing(name = 'Henry') { 
 	return `King ${name} VIII`; 
} 
console.log(makeKing('Louis')); // 'King Louis VIII' 
console.log(makeKing()); // 'King Henry VIII'

上面給引數傳 undefined 相當于沒有傳值,不過這樣可以利用多個獨立的默認值:

function makeKing(name = 'Henry', numerals = 'VIII') { 
 	return `King ${name} ${numerals}`; 
} 
console.log(makeKing()); // 'King Henry VIII' 
console.log(makeKing('Louis')); // 'King Louis VIII' 
console.log(makeKing(undefined, 'VI')); // 'King Henry VI'

在使用默認引數時,arguments 物件的值不反映引數的默認值,只反映傳給函式的引數,當然,跟 ES5 嚴格模式一樣,修改命名引數也不會影響 arguments 物件,它始終以呼叫函式時傳入的值為準:

function makeKing(name = 'Henry') { 
     name = 'Louis'; 
     return `King ${arguments[0]}`; 
} 
console.log(makeKing()); // 'King undefined' 
console.log(makeKing('Louis')); // 'King Louis'

默認引數值并不限于原始值或物件型別,也可以使用呼叫函式回傳的值:

let romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI']; 
let ordinality = 0; 
function getNumerals() { 
     // 每次呼叫后遞增
     return romanNumerals[ordinality++]; 
} 
function makeKing(name = 'Henry', numerals = getNumerals()) { 
     return `King ${name} ${numerals}`; 
} 
console.log(makeKing()); // 'King Henry I'
console.log(makeKing('Louis', 'XVI')); // 'King Louis XVI' 
console.log(makeKing()); // 'King Henry II' 
console.log(makeKing()); // 'King Henry III'

函式的默認引數只有在函式被呼叫時才會求值,不會在函式定義時求值,而且,計算默認值的函式只有在呼叫函式但未傳相應引數時才會被呼叫,

箭頭函式同樣也可以這樣使用默認引數,只不過在只有一個引數時,就必須使用括號而不能省略了:

let makeKing = (name = 'Henry') => `King ${name}`; 
console.log(makeKing()); // King Henry

九、ES2015展開陣列(Spread)

在 ECMAScript5.1 及以前,我們從列印出陣列中的元素很麻煩,最笨的辦法是:

const arr = ['foo', 'bar', 'baz'];
console.log(
	arr[0],
	arr[1],
	arr[2]
)
// foo bar baz

但是當陣列的個數不確定是,就不能使用這個方法,并且這個方法屬于硬展,我們可以使用函式的apply方法,第一個引數this指向console物件,第二個引數是要傳遞的陣列物件:

const arr = ['foo', 'bar', 'baz'];
console.log.apply(console, arr)
// foo bar baz

在ES6中,我們可以更簡單的使用陣列展開的方法,形式同與收集剩余引數,使用…arr展開陣列,這樣寫起來非常方便:

const arr = ['foo', 'bar', 'baz'];
console.log(...arr)
// foo bar baz

十、ES2015箭頭函式

ECMAScript 6 新增了使用胖箭頭(=>)語法定義函式運算式的能力,很大程度上,箭頭函式實體化的函式物件與正式的函式運算式創建的函式物件行為是相同的,任何可以使用函式運算式的地方,都可以使用箭頭函式:

let arrowSum = (a, b) => { 
 	return a + b; 
}; 
let functionExpressionSum = function(a, b) { 
 	return a + b; 
}; 
console.log(arrowSum(5, 8)); // 13 
console.log(functionExpressionSum(5, 8)); // 13

如果只有一個引數,那也可以不用括號,只有沒有引數,或者多個引數的情況下,才需要使用括號:

// 以下兩種寫法都有效
let double = (x) => { return 2 * x; }; 
let triple = x => { return 3 * x; };
// 沒有引數需要括號
let getRandom = () => { return Math.random(); }; 
// 多個引數需要括號
let sum = (a, b) => { return a + b; }; 
// 無效的寫法:
let multiply = a, b => { return a * b; };

箭頭函式也可以不用大括號,但這樣會改變函式的行為,使用大括號就說明包含“函式體”,可以在一個函式中包含多條陳述句,跟常規的函式一樣,如果不使用大括號,那么箭頭后面就只能有一行代碼,比如一個賦值操作,或者一個運算式,而且,省略大括號會隱式回傳這行代碼的值:

// 以下兩種寫法都有效,而且回傳相應的值
let double = (x) => { return 2 * x; }; 
let triple = (x) => 3 * x; 
// 可以賦值
let value = {}; 
let setName = (x) => x.name = "Matt"; 
setName(value); 
console.log(value.name); // "Matt" 
// 無效的寫法:
let multiply = (a, b) => return a * b;

箭頭函式雖然語法簡潔,但也有很多場合不適用,箭頭函式不能使用 arguments、super 和new.target,也不能用作建構式,此外,箭頭函式也沒有 prototype 屬性,

另外,箭頭函式中的this指向也與普通函式不同,請參考一篇文章:

十一、ES2015物件

1.物件字面量的增強

ES6中增強了物件的字面量,在之前,我們宣告物件只能使用鍵+冒號+值的方式:

let bar = '345'
const obj = {
    name: 'leo',
    age: '26',
    bar: bar
}

而在ES6中,當我們的屬性名與其值都為變數且相同時,我們可以省略冒號以及后面的值:

let bar = '345'
const obj = {
    name: 'leo',
    age: '26',
    bar
}

同樣,當我們需要使用動態的屬性名時,之前的做法是在物件宣告過后,再對物件賦值動態屬性名的值:

const obj = {
    name: 'leo',
    age: '26',
    bar
}
obj[Math.random()] = 'random'

在ES6中,我們可以直接使用方括號+運算式對物件添加動態的屬性名,這種方式稱之為【計算屬性名】,方括號內部可以為任意運算式,運算式結果作為最終的屬性名:

const obj = {
    name: 'leo',
    age: '26',
    bar,
    [Math.random()]: 'random'
}

2.Object擴展方法

  • Object.assign

此方法可以將多個源物件中的屬性復制到一個目標物件中,如果物件之間有相同的屬性名,那么源物件中的屬性就會覆寫掉目標物件中的屬性,源物件與目標物件都是普通的物件,只不過用處不同

const source1 = {
      a: 123,
      b: 123
}

const source2 = {
      b: 789,
      d: 789
}

const target = {
      a: 456,
      c: 456
}

const result = Object.assign(target, source1, source2)

console.log(target)
console.log(result === target)
// { a: 123, c: 456, b: 789, d: 789 }
// true

應用場景:

function func (obj) {
      // obj.name = 'func obj'
      // console.log(obj)

      const funcObj = Object.assign({}, obj)
      funcObj.name = 'func obj'
      console.log(funcObj)
}

const obj = { name: 'global obj' }

func(obj)
console.log(obj)

assign方法多用于options物件引數設定默認值,

  • Object.is

用來判斷兩個值是否相等,在之前我們使用=分別判斷值是否相等以及是否全等(值與型別都相等),在==中,js默認使用toString方法來進行隱式轉換,而在ES6中,提供了全新的方法Object.is方法進行判斷:

console.log(
  // 0 == false              // => true
  // 0 === false             // => false
  // +0 === -0               // => true
  // NaN === NaN             // => false
  // Object.is(+0, -0)       // => false
  // Object.is(NaN, NaN)     // => true
)

在實際使用中,仍然建議使用===來判斷,

十二、ES2015 Proxy

在 ES6 之前,ECMAScript 中并沒有類似代理的特性,由于代理是一種新的基礎性語言能力,很多轉譯程式都不能把代理行為轉換為之前的 ECMAScript 代碼,因為代理的行為實際上是無可替代的,為此,代理和反射只在百分之百支持它們的平臺上有用,可以檢測代理是否存在,不存在則提供后備代碼,不過這會導致代碼冗余,因此并不推薦,

1.空代理

最簡單的代理是空代理,即除了作為一個抽象的目標物件,什么也不做,默認情況下,在代理物件上執行的所有操作都會無障礙地傳播到目標物件,因此,在任何可以使用目標物件的地方,都可以通過同樣的方式來使用與之關聯的代理物件,

如下面的代碼所示,在代理物件上執行的任何操作實際上都會應用到目標物件,唯一可感知的不同就是代碼中操作的是代理物件,

const target = { 
 	id: 'target' 
}; 
const handler = {}; 
const proxy = new Proxy(target, handler); 
// id 屬性會訪問同一個值
console.log(target.id); // target 
console.log(proxy.id); // target 
// 給目標屬性賦值會反映在兩個物件上
// 因為兩個物件訪問的是同一個值
target.id = 'foo'; 
console.log(target.id); // foo 
console.log(proxy.id); // foo 
// 給代理屬性賦值會反映在兩個物件上
// 因為這個賦值會轉移到目標物件
proxy.id = 'bar'; 
console.log(target.id); // bar 
console.log(proxy.id); // bar 
// hasOwnProperty()方法在兩個地方
// 都會應用到目標物件
console.log(target.hasOwnProperty('id')); // true 
console.log(proxy.hasOwnProperty('id')); // true 
// Proxy.prototype 是 undefined 
// 因此不能使用 instanceof 運算子
console.log(target instanceof Proxy); // TypeError: Function has non-object prototype 
'undefined' in instanceof check 
console.log(proxy instanceof Proxy); // TypeError: Function has non-object prototype 
'undefined' in instanceof check 
// 嚴格相等可以用來區分代理和目標
console.log(target === proxy); // false

2.定義捕獲器:

使用代理的主要目的是可以定義捕獲器(trap),捕獲器就是在處理程式物件中定義的“基本操作的攔截器”,每個處理程式物件可以包含零個或多個捕獲器,每個捕獲器都對應一種基本操作,可以直接或間接在代理物件上呼叫,每次在代理物件上呼叫這些基本操作時,代理可以在這些操作傳播到目標物件之前先呼叫捕獲器函式,從而攔截并修改相應的行為,

例如,可以定義一個 get()捕獲器,在 ECMAScript 操作以某種形式呼叫 get()時觸發,下面的例子定義了一個 get()捕獲器:

const target = { 
 	foo: 'bar' 
}; 
const handler = { 
     // 捕獲器在處理程式物件中以方法名為鍵
     get() { 
     	return 'handler override'; 
     } 
}; 
const proxy = new Proxy(target, handler); 
console.log(target.foo); // bar 
console.log(proxy.foo); // handler override 
console.log(target['foo']); // bar 
console.log(proxy['foo']); // handler override 
console.log(Object.create(target)['foo']); // bar 
console.log(Object.create(proxy)['foo']); // handler override

捕獲器可以定義get、delete、set等方法,

十三、ES2015 class類

ECMAScript 6 新引入的 class 關鍵字具有正式定義類的能力,類(class)是ECMAScript 中新的基礎性語法糖結構,因此剛開始接觸時可能會不太習慣,雖然 ECMAScript 6 類表面上看起來可以支持正式的面向物件編程,但實際上它背后使用的仍然是原型和建構式的概念,

1.類的定義

與函式型別相似,定義類也有兩種主要方式:類宣告和類運算式,這兩種方式都使用 class 關鍵字加大括號:

// 類宣告
class Person {} 
// 類運算式
const Animal = class {};

類可以包含建構式方法、實體方法、獲取函式、設定函式和靜態類方法,但這些都不是必需的,空的類定義照樣有效,默認情況下,類定義中的代碼都在嚴格模式下執行,

與函式建構式一樣,多數編程風格都建議類名的首字母要大寫,以區別于通過它創建的實體(比如,通過 class Foo {}創建實體 foo):

// 空類定義,有效 
class Foo {} 
// 有建構式的類,有效
class Bar { 
 	constructor() {} 
} 
// 有獲取函式的類,有效
class Baz { 
 	get myBaz() {} 
} 
// 有靜態方法的類,有效
class Qux { 
 	static myQux() {} 
}

2.類建構式

constructor 關鍵字用于在類定義塊內部創建類的建構式,方法名 constructor 會告訴解釋器在使用 new 運算子創建類的新實體時,應該呼叫這個函式,建構式的定義不是必需的,不定義建構式相當于將建構式定義為空函式,

使用 new 運算子實體化 Person 的操作等于使用 new 呼叫其建構式,唯一可感知的不同之處就是,JavaScript 解釋器知道使用 new 和類意味著應該使用 constructor 函式進行實體化,

使用 new 呼叫類的建構式會執行如下操作,

  • 在記憶體中創建一個新物件,

  • 這個新物件內部的[[Prototype]]指標被賦值為建構式的 prototype 屬性,

  • 建構式內部的 this 被賦值為這個新物件(即 this 指向新物件),

  • 執行建構式內部的代碼(給新物件添加屬性),

  • 如果建構式回傳非空物件,則回傳該物件;否則,回傳剛創建的新物件,

class Animal {} 
class Person { 
     constructor() { 
     	console.log('person ctor'); 
     } 
} 
class Vegetable { 
     constructor() { 
     	this.color = 'orange'; 
     } 
} 
let a = new Animal(); 
let p = new Person(); // person ctor 
let v = new Vegetable(); 
console.log(v.color); // orange

3.實體、原型、類成員

類的語法可以非常方便地定義應該存在于實體上的成員、應該存在于原型上的成員,以及應該存在于類本身的成員,

每次通過new呼叫類識別符號時,都會執行類建構式,在這個函式內部,可以為新創建的實體(this)添加“自有”屬性,至于添加什么樣的屬性,則沒有限制,另外,在建構式執行完畢后,仍然可以給實體繼續添加新成員,

每個實體都對應一個唯一的成員物件,這意味著所有成員都不會在原型上共享:

class Person { 
     constructor() { 
         // 這個例子先使用物件包裝型別定義一個字串
         // 為的是在下面測驗兩個物件的相等性
         this.name = new String('Jack'); 
         this.sayName = () => console.log(this.name); 
         this.nicknames = ['Jake', 'J-Dog'] 
     } 
} 
let p1 = new Person(), 
 	p2 = new Person(); 
p1.sayName(); // Jack 
p2.sayName(); // Jack 
console.log(p1.name === p2.name); // false 
console.log(p1.sayName === p2.sayName); // false 
console.log(p1.nicknames === p2.nicknames); // false 
p1.name = p1.nicknames[0]; 
p2.name = p2.nicknames[1]; 
p1.sayName(); // Jake 
p2.sayName(); // J-Dog

靜態類成員在類定義中使用 static 關鍵字作為前綴,在靜態成員中,this 參考類自身,其他所有約定跟原型成員一樣:

class Person { 
     constructor() { 
         // 添加到 this 的所有內容都會存在于不同的實體上
         this.locate = () => console.log('instance', this); 
     } 
     // 定義在類的原型物件上
     locate() { 
        console.log('prototype', this); 
     } 
 	// 定義在類本身上
     static locate() { 
        console.log('class', this); 
     } 
} 
let p = new Person(); 
p.locate(); // instance, Person {} 
Person.prototype.locate(); // prototype, {constructor: ... } 
Person.locate(); // class, class Person {}

4.繼承

ES6 類支持單繼承,使用 extends 關鍵字,就可以繼承任何擁有[[Construct]]和原型的物件,很大程度上,這意味著不僅可以繼承一個類,也可以繼承普通的建構式(保持向后兼容):

class Vehicle {} 
// 繼承類
class Bus extends Vehicle {} 
let b = new Bus(); 
console.log(b instanceof Bus); // true 
console.log(b instanceof Vehicle); // true 
function Person() {} 
// 繼承普通建構式
class Engineer extends Person {} 
let e = new Engineer(); 
console.log(e instanceof Engineer); // true 
console.log(e instanceof Person); // true

十四、ES2015 Set資料結構

ECMAScript 6 新增的 Set 是一種新集合型別,為這門語言帶來集合資料結構,Set 在很多方面都像是加強的 Map,這是因為它們的大多數 API 和行為都是共有的,

使用 new 關鍵字和 Set 建構式可以創建一個空集合:

const m = new Set();
// 使用陣列初始化集合 
const s1 = new Set(["val1", "val2", "val3"]); 
alert(s1.size); // 3 
// 使用自定義迭代器初始化集合
const s2 = new Set({ 
     [Symbol.iterator]: function*() { 
         yield "val1"; 
         yield "val2"; 
         yield "val3"; 
     } 
}); 
alert(s2.size); // 3

初始化之后,可以使用 add()增加值,使用 has()查詢,通過 size 取得元素數量,以及使用 delete()和 clear()洗掉元素:

const s = new Set(); 
alert(s.has("Matt")); // false 
alert(s.size); // 0 
s.add("Matt") 
 .add("Frisbie"); // add函式回傳的依然是set物件,所以可以使用鏈式呼叫
alert(s.has("Matt")); // true 
alert(s.size); // 2 
s.delete("Matt"); 
alert(s.has("Matt")); // false 
alert(s.has("Frisbie")); // true 
alert(s.size); // 1 
s.clear(); // 銷毀集合實體中的所有值
alert(s.has("Matt")); // false 
alert(s.has("Frisbie")); // false 
alert(s.size); // 0

十五、ES2015 Map資料結構

作為 ECMAScript 6 的新增特性,Map 是一種新的集合型別,為這門語言帶來了真正的鍵/值存盤機制,Map 的大多數特性都可以通過 Object 型別實作,但二者之間還是存在一些細微的差異,具體實踐中使用哪一個,還是值得細細甄別,

使用 new 關鍵字和 Map 建構式可以創建一個空映射:

const m = new Map();

如果想在創建的同時初始化實體,可以給 Map 建構式傳入一個可迭代物件,需要包含鍵/值對陣列,可迭代物件中的每個鍵/值對都會按照迭代順序插入到新映射實體中:

// 使用嵌套陣列初始化映射
const m1 = new Map([ 
     ["key1", "val1"], 
     ["key2", "val2"], 
     ["key3", "val3"] 
]); 
alert(m1.size); // 3 

// 映射期待的鍵/值對,無論是否提供
const m3 = new Map([[]]); 
alert(m3.has(undefined)); // true 
alert(m3.get(undefined)); // undefined
const m = new Map()

const tom = { name: 'tom' }

m.set(tom, 90)

console.log(m)

console.log(m.get(tom))

// 輸出
// Map { { name: 'tom' } => 90 }
// 90
// 90 { name: 'tom' }

同樣,map也有has()、delete()、clear()方法,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/204372.html

標籤:python

上一篇:快速排序(分治策略)

下一篇:一道阿里web前端面試題看出你的JS基本功

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more