JavaScript 構文
大文字と小文字を区別
JavaScript ではすべて大文字と小文字が区別されます。変数、関数、演算子はすべて大文字と小文字が区別されます。
例: test と Test は 2 つの異なる変数です
識別子
いわゆる識別子は、変数、関数、属性、関数パラメーターの名前を指します。
識別子は 1 つ以上の文字で構成できます
最初の文字は文字、アンダースコア、ドル記号である必要があります
残りの文字には文字を含めることができます、アンダースコア、ドル記号、数字
慣例によれば、識別子は通常キャメルケースを使用します。つまり、最初の単語の最初の文字は小文字で、後続の各単語の最初の文字は大文字です。 a>
この記述方法は必須ではありませんが、この記述方法はJavaScript
組み込み関数およびオブジェクトの命名方法と一致しているため、推奨されます< /span>
例: firstSecond、myCar、
コメント
JavaScript は、単一行コメントや複数行コメントなど、コードにコメントを付けるときに C 言語スタイルを採用します。
// 单行注释
/*
多行注释
*/
コメントのショートカット キー:/+Ctrl
厳密モード
厳密モードは、別の JavaScript 解析および実行モデルです。非標準の書き込みはこのモードで処理され、安全でないアクティビティに対してエラーがスローされます。スクリプト全体で厳密モードを有効にするには、以下を追加する必要があります。
"use strict";
同時に、厳密モードでは、関数本体の先頭に次の前処理命令を置くだけで、厳密モードで実行される関数を指定することもできます。
function doSomething() {
"use strict";
//函数体
}
声明
JavaScript
ステートメントはセミコロンで終わり、省略記号は、ステートメントがどこで終わるかを決定するのはパーサー次第であることを意味します。
let sum = a + b //不推荐
let diff = a + b; //推荐
- セミコロンを追加すると、省略による問題を防ぐことができます。
- 不完全な入力内容によって引き起こされる問題を回避できます。
- 同時に、セミコロンを追加すると、圧縮コードの空行を削除することもできます。
- 場合によってはパフォーマンスの向上にも役立ちます (パーサーは、いつ、どこにセミコロンを追加します)
複数のステートメントを 1 つの C スタイル コード ブロックに結合できます。コード ブロックは左中括弧で始まり、右中括弧で終わります。
if(test) {
test = false;
console.log(test)
}
複数のステートメントを実行する場合は、エラーを防ぐための明確な構造を持つコード ブロックが必要です。 (ベストプラクティス)
// 有效 不推荐
if(test)
console.log(test)
// 推荐
if(test) {
console.log(test)
}
キーワード、予約語
ECMA-262 では、多くのキーワードと将来の予約語が予約されることが規定されており、これらのキーワードには特別な用途があります。
// 关键字
break do in typeof
case else instanceof var
catch export new void
class extends return while
const finally super with
continue for switch yield
debugger function this
default if throw
delete import try
// 未来保留字---这些虽然还不是关键字但是未来可能会成关键字所以不推荐使用成标识符
// 始终保留
enum
// 严格模式下保留
implements package public
interface protected static
let provate
// 模块代码中保留
await
変数
JavaScript
の変数の定義は緩いため、変数にはあらゆるタイプのデータを保持できます。各変数は、任意の値を保持するために使用される名前付きプレースホルダーにすぎません。ES
すべてのバージョンを使用できますvar
、ES6
将来も使用できますlet
、< /a >const
だった
var message
このコードは変数を定義しますmessage
。この変数はあらゆるタイプの値を保存するために使用できます。初期化されていない場合、変数は特別な値を保存しますundefined
var message = "hi"
このコードは変数を定義しますmessage
。同時に初期化して変数に値を割り当てます。ここで変数を保存および変更できます。
var 宣言スコープ
var 演算子を使用して定義された変数は、他の関数を含むローカル変数になります。
function test(){
var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
逆に、演算子を使用しない場合は、グローバル変数が作成されます。
function test(){
message = "hi"; // 局部变量
}
test();
console.log(message); // "hi"
グローバル変数を関数内でローカルに定義すると保守が難しく、問題が発生する可能性があることに注意してください。 var が意図的に省略されたかどうかわからないからです。
var
を使用して複数の変数を定義する場合、カンマを使用して各変数とオプションの初期化を 1 つのステートメントで区切ることができます。
var message = "hi",
found = false,
age = 29;
// 这里的定义只是为了方便阅读
var ステートメントの巻き上げ
function foo(){
console.log(age);
var age = 26;
}
foo(); // undefined
JavaScript ランタイムは上記のコードを次のコードと同等とみなすため、この関数はエラーを報告しません。
function foo(){
var age
console.log(age);
age = 26;
}
foo(); // undefined
これはいわゆる変数プロモーションです。つまり、すべて变量声明提升到函数作用域顶部
が同時に返されます。var を使用して同じ変数を複数回宣言しても問題はありません (< /span>值得注意的是变量提升的是变量,不是变量的值
)
function foo(){
var age = 16;
var age = 26;
var age = 36;
console.log(age);
}
foo(); // 36
同時に、全局下声明的变量会成为Windows的属性
- スコープを宣言する
- ステートメントのプロモーション
- グローバルに使用される
var
は、トップレベル オブジェクトのプロパティになりますwindows
させて
var操作符
と比較すると、 は同様の機能を持ちますが、明らかな違いは次のとおりです。 var
、、let
let はブロックスコープを宣言します
if (true) { let age = 26; console.log(age); // 26 } console.log(age); // ReferenceError:age 没有定义
var は関数のスコープを宣言します
if (true) { var name = "Matt"; console.log(name); // Matt } console.log(name); // Matt
こちら
age
if ブロックの外で変数を参照できない理由は、変数のスコープがブロック内に制限されているためです。块作用域是函数作用域的子集
であるため、var
のスコープ制限は にも適用されます。let
let
同じブロック スコープ内での重複した宣言も許可されません。これもエラーになります:
var age;
var age;
let name;
let name; // SyntaxError; 标识符name已经声明过了
同じブロック内に重複した宣言がないため、ネストされた識別子についてはエラーは報告されません。
var name = "Nicholas";
console.log(name); // "Nicoholas"
if(true){
var name = "Matt";
console.log(name); // "Matt"
}
let age = 30;
console.log(age); // 30
if(){
let age = 16;
console.log(age); // 16
}
これら 2 つのキーワードは、異なる型の変数を宣言するのではなく、变量在相关作用域如何存在
一時的なデッド ゾーン
let
宣言された変数がプロモートされなくなることを示しているだけです。範囲内。 let
が宣言される前の実行の瞬間は、「暂时性死区
」と呼ばれます。この段階で後から宣言された変数への参照は、 をスローします。ReferenceError
// name会被提升
console.log(name); // undefined
var name = "Matt";
// age 不会被提升
console.log(age); // ReferenceError :age
var age = 16;
グローバル宣言
let
を使用して宣言された変数は、グローバルには Windows オブジェクトの属性にはなりません。var
は、 を使用して宣言されます。あ>
var name = "Matt";
console.log(window.name); // "Matt"
let age = 26;
console.log(window.age); // undefined
条件文
var
を使用すると、文が昇格されるため、JS
エンジンは自動的に Statement< /span> のため、let ステートメントが以前に使用されたかどうかはチェックされず、ステートメントなしで let ステートメントを宣言することは不可能です。 在作用域的顶部合并成一个声明
。 let的作用域是块
は、
try/catch
ステートメントまたはtypeof
演算子を使用して解決できません。条件ブロック内のlet声明
のスコープが異なるためです。ブロックに限定されます。
の前の for ループ内の let ステートメント
、 ループで定義された変数は外部に浸透します。ループ body を使用し、 を使用すると、この問題が解決されます。 let
for
let
for(var i = 0 ; i < 5; ++i){
//循环逻辑
}
console.log(i); // 5
for(let i = 0 ; i < 5; ++i){
//循环逻辑
}
console.log(i); // ReferenceError :i 没有定义
for(var i = 0 ; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}
console.log(i); // 5,5,5,5,5
for(let i = 0 ; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}
console.log(i); // 0,1,2,3,4
var
を使用して変数を宣言する場合の一般的な問題は、反復変数の奇妙な宣言と変更です。let
を使用して反復変数を宣言する場合、 a>JS引擎在后台会为每一个迭代循环声明一个新的迭代变量。每个setTimeout引用的都是不同的变量实例
。
定数
const
の動作は基本的に let
の動作と同じです。唯一の重要な違いは、これを使用して変数を宣言する場合、変数を初期化して変数を変更する必要があることです。 const
で宣言すると実行時エラーが発生します
const age = 26;
age = 36; // TypeError:给常量赋值
// const 也不允许重复声明
const name = "Matt";
const name = "Nicholas"; // SyntaxError
// const 声明的作用域也是块
const name = "Matt";
if(){
const name = "Nicholas";
}
console.log(name); // Matt
var、let、constの違い
var: 変数宣言のプロモーション、スコープのプロモーション、
let: 一時的なデッド ゾーン、ブロックレベルのスコープ、初期化なし、
const: ステートメント同時に初期化する必要があり、変更するとエラーが報告されます。
JavaScriptのデータ型
JavaScript
には、基本データ型Undefined、Null、Boolean、Number、String、Symbol、Bigint
と参照データ型があります。Object
データ型の検出
JS
の型システムは緩いため、変数のデータ型を決定する手段が必要です
の種類
typeof
プリミティブ型の場合、null を除く正しい型を表示できます。
typeof
関数を除くオブジェクトの場合、正しい型を表示できます。object
typeof
は変数の型を正確に判断できないため、オブジェクトの正しい型を判断したい場合は、instanceof
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){
}); // function
console.log(typeof {
}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object null 的数据类型被 typeof 解释为 object
インスタンスの
instanceof
は、オブジェクトのタイプを正確に判断できます。内部メカニズムは、そのタイプのプロトタイプがオブジェクトのプロトタイプ チェーン内で見つかるかどうかを判断することであるためです。
instanceof
は、オブジェクトのタイプを正確に判断できます。複雑な参照データ型ですが、基本データ型を正しく決定できません。
とtypeof
にも欠点があります。基本データ型を決定できますが ( 型を除き、他の型は判定できませんnull
)、ただし、参照データ型のうちfunction
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){
} instanceof Function); // true
console.log({
} instanceof Object); // true
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
// 我们也可以试着实现一下 instanceof
function _instanceof(left, right) {
// 由于instance要检测的是某对象,需要有一个前置判断条件
//基本数据类型直接返回false
if(typeof left !== 'object' || left === null) return false;
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.__proto__
// 判断对象的类型是否等于类型的原型
while (true) {
if (left === null)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
console.log('test', _instanceof(null, Array)) // false
console.log('test', _instanceof([], Array)) // true
console.log('test', _instanceof('', Array)) // false
console.log('test', _instanceof({
}, Object)) // true
constructor
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {
}).constructor === Function); // true
console.log(({
}).constructor === Object); // true
//如果我创建一个对象,更改它的原型,constructor就会变得不可靠了
function Fn(){
};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
Object.prototype.toString.call()
toString() は Object のプロトタイプ メソッドであり、このメソッドを呼び出すと、一律に "[object Xxx]" (Xxx はオブジェクトの種類) の形式で文字列を返すことができます。 Object オブジェクトの場合、toString() を直接呼び出すと [object Object] が返されますが、他のオブジェクトの場合は、これを呼び出して正しい型情報を返す必要があります。
Object.prototype.toString({
}) // "[object Object]"
Object.prototype.toString.call({
}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){
}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
// 从上面这段代码可以看出,Object.prototype.toString.call() 可以很好地判断引用类型,甚至可以把 document 和 window 都区分开来。
// 全局下判断数据类型
function getType(obj){
let type = typeof obj;
// 先进行typeof判断,如果是基础数据类型,直接返回
if (type !== "object") {
return type;
}
// 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
// 注意正则中间有个空格
}
// 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){
}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回
未定義
データ型の値は 1 つだけです Undefined
undefined
。
使用
var
let
変数を定義しますが、初期化されていない場合、この変数の値はundefined
var age; let name; console.log(age == undefined); // true console.log(name == undefined); // true
注: 変数を明示的に未定義に設定しないでください。
undefined值主要用于比较,这个值的目的是为了正式明确空对象指针和未初始化变量的区别
初期化されていない変数や未定義の変数は
typeof
を使用して、戻り値がすべてundefined
であるかどうかを判断するため、変数を定義するときにすぐにそれを行う必要があります。初期化。変数がundefined
を返したときに这个变量是未声明而不是声明了但是没有初始化
をすぐに知ることができます。let message; if(message){ //这块不会执行 } if(!message){ //这块会执行 } if(age){ // 这块会报错 }
ヌル
データ型の値も 1 つだけです Null
null
。
論理的に言えば、
null
値は null ポインタ オブジェクトを表します。これもtypeof
渡されます。null
が戻る理由object
let car = null; console.log(typeof car); // object
undefined
値は unll
から導出されるため、 undefined
は表面的には unll
と同等です。ただし、この 2 つの目的は異なります。どの変数についても、明示的に変数値を undefined
に設定する必要はありません。ただし、その内容がわからない場合は、変数に入力するコンテンツは、null
で入力できます。これにより、null オブジェクト ポインタのセマンティクスを維持し、 undefined
とさらに区別できます。
ブール値
データ型の中でBoolean
は、最も頻繁に使用される型の 1 つですJavaScript
。これには 2 つの値がありますtrue
とfalse
。
Boolean
に関しては、さまざまな型とブール値の間の変換ルールを知っておく必要があります。
データの種類 | 真の値に変換する | false 値に変換する |
---|---|---|
Boolean | 真実 | 間違い |
弦 | 空でない文字列 | " " (空の文字列) |
番号 | ゼロ以外の値(無限大を含む) | 0、NaN |
物体 | あらゆるオブジェクト | ヌル |
Undefined | N/A (存在しません) | 未定義 |
これらの変換の内容を理解する必要がある理由は、他の型からブール型への変換が制御フロー ステートメントで自動的に実行されるためです。
let message = "hello world!";
if(message){
console.log("value is true");
}
// 这里可以看到message是字符串,但是console.log()会输出 "value is true" 。
// 因为这里message会自动的转换为等价的 true
Number
Number
データ型については、まずどのように記述するかを決定します。基本システムに従って、 Number
は次のように記述できます。
// 最基本的数值字面量格式是十进制,直接写出来就可以
// 十进制。(不用前缀)
let num = 55; // 整数
// 二进制。(前缀0b 或 0B ,逢二进一)
let num21 = 0b10; // 2
let num22 = 0b100; // 4
// 八进制。(前缀 0 ,逢八进一 )
let num31 = 070; // 56
let num32 = 010; // 56
// 十六进制。(前缀 0x 或 0X ,逢十六进一)
let num41 = 0xA; // 10
let num42 = 0x1f; // 31
注意:在严格模式下八进制是无效的,会导致JavaScript引擎抛出错误。同时八进制字面量第一个数字必须是0,然后是相应的八进制数字(0-7).如果字面量中包含的数字超过有效的范围,后面的序列就会成为十进制。
除此之外,使用八进制和十六进制格式创建的数值在所有的数学操作中都被视为十进制
let num1 = 070; // 56
let num2 = 079; // 79 9超过八进制的取值,所以num2以及下面的num3成10进制
let num3 = 08; // 8
つづく。 。 。