JSのプロパティにはなぜ''がいらないのか?

このQ&Aのポイント
  • JSのプロパティにはなぜ''がいらないのか?文字列ではない理由を解説します。
  • 変数、オブジェクト、配列の再代入時にletを省略できる理由を解説します。
  • 再宣言のlet省略と再代入を区別する方法について解説します。
回答を見る
  • ベストアンサー

JSのプロパティはなぜ下記のように''がいらない?

JSのプロパティはなぜ下記のように''がいらないのでしょうか? 恐らく文字列ではないという理由なんでしょうが、文字列に初心者には見えます。 let person = { 'age': 20, }; プロパティが文字列でない理由を教えていただければ幸いです。 また、変数、オブジェクト、配列は再代入時にletを省略できますが、これは change 上書き。再代入の時はletはいらない。前に オブジェクトなどは宣言済みで、すでに存在するので、再宣言をして、再度作る必要はないという事でよろしいでしょうか。 つまり宣言をすることが作成することという事ですね。 例 let person = { age: 20, }; person.age = 16; また再宣言のlet省略と再代入が同じ見た目でこんがらがるのですが、 どのように区別できるのでしょうか? 初心者にもわかるように解説していただけるとありがたいです。

noname#226032
noname#226032

質問者が選んだベストアンサー

  • ベストアンサー
  • bya00417
  • ベストアンサー率35% (56/158)
回答No.6

> これは二度目はvarを省略して、再宣言していると考えるのは間違えで、これは100%再代入と考えてよいという事でしょうか? はい、var が無い場合は変数の宣言ではなく、代入演算子を使った処理です。 > letは再代入は化で、再宣言は不可という事なので再宣言のlet、const省略はないですが、varの場合はどうですか? let はブロックスコープの「変数」なので、中の値はいつでも書き換え可能です。 再宣言は ECMAScript の規定でエラーにすることになっているので不可です。 const は「定数」なので、一度宣言して値をセットしたら変更不可能なので再宣言も再代入もできません。 var は「変数」なので、中の値はいつでも書き換え可能です。 再宣言については var は出来るのですが、言語エンジン内での処理としては var 宣言を無視するだけです。 これも ECMAScript の規定で定められており、var の処理としては「変数が存在しなければ変数を作る」と言う事になっているので、変数が存在したら新たに作ることはせず次の処理に進むだけです。 var と let の扱いの違いは歴史的なものもあって複雑な話なのですが、後から出てきた let の方が他のプログラム言語と同じ厳密な振る舞いになっていて、古くから存在する var は JavaScript 特有の緩い振る舞いをしています。

noname#226032
質問者

お礼

a = 2は再代入なので、 二度目からの再宣言はvarの省略ができるという情報は間違えなのですかね。 varがなければ必ず再代入で、 varがあれば必ず宣言。二度目なら再宣言という事ですね。

noname#226032
質問者

補足

varのみ再宣言ができるが、言語エンジン内での処理としては var 宣言を無視するという事ですが、 無視とはvarを無視して再代入として考えるという事ですか? それとも再宣言自体がなかったことにするという事でしょうか? ブロックスコープと関数スコープのさもなんだかよくわからないのですが、 教えていただければ幸いです。

その他の回答 (6)

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.7

そもそも、「再宣言」という言葉をこれ程普通に使うこと自体があり得ません。 varでは何回宣言文を書いても意味はありませんし、letやconstではエラーとなります そのため「再宣言する」ということ自体が、それは意味が無いことだよと言う以外に意味のないことなのです 運動会の開催宣言を2回することを考えたとしましょう。 そしてそれを「再宣言」と呼ぶことの滑稽さが分かりますか? それはただ宣言を二回しただけです。 「再宣言」というとさも意味のあるように聞こえますが、 実際意味は無いですし、普通に使われる言葉ではないので、 使うと何の意図があって言っているのかと驚かれるかもしれませんよ。

noname#226032
質問者

お礼

再宣言にも必ずvarが必要で、varの省略という概念自体がなく、 varがないものはただの代入であるという事ですね。 こちらの認識はまず正しいのですね。 そして再代入は良く行うものの再宣言という行為はほとんど行われなという事ですね。 単語としても使われないというのはびっくりしました。

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.5

100%再代入ですよ。 varやletが付いた文を宣言文と言うので、付かなければ宣言になりようがありません。 sloppyモード(非strictモード)中では変数宣言なしに変数を代入するとグローバル変数となりますが、それも宣言とは言いません。 varの場合は何度も宣言することが許されていますが、別に2つ目、3つ目のvarが意味を持つことはありません。

noname#226032
質問者

お礼

>> varやletが付いた文を宣言文と言うので、付かなければ宣言になりようがありません。 一度宣言をしておけばvarは次から省略できるという情報は嘘だったのですね。 再宣言にも必ずvarが必要で、varの省略という概念自体がなく、 varがないものはただの代入であるという事ですね。

  • bya00417
  • ベストアンサー率35% (56/158)
回答No.4

> すると再宣言とは実は再代入の事を示す別の言い方になるのでしょうか? そもそも再宣言は Syntax Error になり、その場で処理が中断します。 先の回答にも書いた通り let はブロックスコープなので、ブロックが異なれば別変数として扱われるので、あなたが再宣言だと思っているのは実は別ブロックで宣言が行われているものじゃないでしょうか。

noname#226032
質問者

お礼

var a = 1 a = 2 というソースをよく見るのですが、これは二度目はvarを省略して、 再宣言していると考えるのは間違えで、 これは100%再代入と考えてよいという事でしょうか? letは再代入は化で、再宣言は不可という事なので再宣言のlet、const省略はないですが、varの場合はどうですか?

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.3

『再宣言とは実は再代入の事を示す』ということもあり得ません。 「宣言」と「代入」は別の独立した事柄です。 変に混乱しているようですが、話はシンプルです。 let abc これが宣言 abc = 123 これが代入 let abc = 123 これは宣言して代入(初期化) ただし、 let abc は実際は let abc = undefined の省略形と考えてください letは再代入は可能です。再宣言が不可なのです。 constの場合は、再代入も不可です

noname#226032
質問者

お礼

var a = 1 a = 2 というソースをよく見るのですが、これは二度目はvarを省略して、 再宣言していると考えるのは間違えで、 これは100%再代入と考えてよいという事でしょうか?

  • bya00417
  • ベストアンサー率35% (56/158)
回答No.2

プロパティ名に '' が必用無いのは、それがデータでは無いからです。 変数を宣言する時に変数名に '' を付けないのと同じと考えましょう。 そもそもプロパティとはオブジェクト内の変数の事ですから、プロパティ名は変数名と同義です。 データを変数に代入する時は、変数名なのかデータなのかを区別する必要があるのでデータの場合は '' で囲って区別させているのです。 let はブロックスコープの変数を新たに使用開始する宣言(命令)です。 JavaScript 言語エンジンは let を見つけるとメモリ上に変数保存領域を確保します。 一度宣言されt変数に新たな値を入れる場合、すでにメモリ上に保存領域が確保されているので新たな領域確保は必要ないので let が不要と言うことになります。 > また再宣言のlet省略と再代入が同じ見た目でこんがらがる let で作られた変数はブロックスコープです。 例えば function hoge () { let abc = 0; } function fuga () { let abc = 100; } と、違うブロック内( { から } の間)で宣言された abc 変数は、別物として扱われるため、それぞれが独立して異なる内容を保持できますので、どのブロックに属する変数なのかについて注意する必要があります。

noname#226032
質問者

お礼

>>> そもそもプロパティとはオブジェクト内の変数の事ですから、プロパティ名は変数名と同義です。 データを変数に代入する時は、変数名なのかデータなのかを区別する必要があるのでデータの場合は '' で囲って区別させているのです。 プロパティとはオブジェクト内の変数の事だったんですね。 それは知りませんでした。 つまり オブジェクトの外:中 プロパティ:変数 プロパティ名:変数名 プロパティの値:変数の中の値 関数:メソッド と同じという関係になっているという事でしょうか? 確かに変数名は文字列と区別するために''はつけないですね。 よってプロパティ名も''を付けないという事ですね。 >>> let はブロックスコープの変数を新たに使用開始する宣言(命令)です。 JavaScript 言語エンジンは let を見つけるとメモリ上に変数保存領域を確保します。 一度宣言されt変数に新たな値を入れる場合、すでにメモリ上に保存領域が確保されているので新たな領域確保は必要ないので let が不要と言うことになります。 一度目にlet name =と宣言した時点でメインメモリーの一部の領域をname変数が確保しているので、 name変数に別の値を再代入、上書きをしたい時は宣言letは不要という事ですね。 すると再宣言とは実は再代入の事を示す別の言い方になるのでしょうか? イコールと考えてよいのですかね?

  • b0a0a
  • ベストアンサー率49% (156/313)
回答No.1

プロパティ名に関しては文字列ですが、省略できるというだけです。クォーテーションを付けても構いませんよ。 letに関しては省略できるのではなく、2度使ってはいけない決まりです。 一度しか宣言できません。再宣言と言うことはできません。

noname#226032
質問者

お礼

letは再代入が不可ですが再宣言も不可なのでしたっけ? もしかして、再宣言とは実は再代入の事を示す別の言い方になるのでしょうか? イコールと考えてよいのですかね?

関連するQ&A

  • 外部jsファイルの変数に代入するには?

    初心者ですがjavascriptについて質問です。 なんらかの値を外部ファイル内の変数に代入させることは可能なのでしょうか? うまく説明できませんが・・・ あるjsファイル内の文字をリンク先の外部jsファイル内の変数の中に入れたいです。 <例> abc.js の中にある文字列"○○○" ↓ abc.jaから <a href="xyz.js">にリンク ↓ xyz.js の中の var xxx ="○○○" に、したいのですが・・・説明が下手ですみません。 わかる方是非教えてください。

  • thisとvar ?

    javascript初心者です。 コンストラクタ(プロトタイプ)とクロージャを学んでいますが、 コンストラクタ(プロトタイプ)では、関数内にthisで変数宣言、クロージャはvarで宣言しています。 この違いの理由は何でしょうか?漠然とした質問ですみません。 thisとvarでの変数宣言の違いなど教えていただけないでしょうか? コンストラクタ-------------------- function Person(n){ this.name = n; } Person.prototype.city = 'Tokyo'; Person.prototype.moveTo = function(c){ document.write(this.name + ': Moving to... ' + c + '<br>'); Person.prototype.city = c; } クロージャ------------------- function Person(n, a){ var name = n; var age = a; return { getName: function() { return name; }, setAge: function(i){ if( 0<= i ){ age = i; } }, getAge: function(){ return age; } } }

  • thisで定義したプロパティが継承できない

    以下のようなコードがあります。 function inherit(subClass, superClass) { for (var prop in superClass.prototype) { if (typeof(subClass.prototype[prop]) == "undefined") { subClass.prototype[prop] = superClass.prototype[prop]; } } } /* class Personal */ { function personal() { this.sex = "男"; } personal.prototype = { "hello" : "こんにちは", "fName" : "苗字", "lName" : "名前", "age" : "年齢" } } /* class Taku17 */ { function taku17() { this.lName = "taku17"; } taku.prototype = { "fName" : "Secret", "age" : 21, "tall" : "1234cm", "height" : "5678Kg", "getFullName" : function() { return this.fName+" "+this.lName; } }; inherit(taku17, personal); } var source = ""; window.onload = function() { var person1 = new taku17(); source += "person1.hello = "+person1.hello+"<br />"; source += "person1.fName = "+person1.fName+"<br />"; source += "person1.lName = "+person1.lName+"<br />"; source += "person1.age = "+person1.age+"<br />"; source += "person1.sex = "+person1.sex+"<br />"; source += "person1.tall = "+person1.tall+"<br />"; source += "person1.height = "+person1.height+"<br />"; source += "person1.getFullName() = "+person1.getFullName()+"<br /><br />"; document.getElementById("result").innerHTML = source.replace(/undefined/g, "<font color=\"#ff0000\">undefined</font>"); } Javascriptでクラス化と継承を実現するためのコードなのですが、出力される情報のうちsexの情報だけがundefinedになってしまいます。sexプロパティはpersonal関数(コンストラクタのつもり)内にthis.sexとして定義してあり、他のプロパティはprototypeで定義してあります。このsexプロパティも継承するにはどのようにしたら良いのでしょうか?色々試してみましたが、そもそもsexプロパティにアクセスする方法から分かりません。

  • jsで特定の位置から文字列を取得したい

    例えば、 ----------------------------- var hoge = 'name=Hanako&age=20&day=20'; ----------------------------- という文字列があったとして、 「age=」という文字列があった場合のみ、 「age=」の後ろ2文字をアラートで表示させたいのですが どのように組めば良いのでしょうか…。 ↓途中ですが、こんな感じで組んでいました。 ----------------------------- var kensaku = hoge.search(/age=/); if (kensaku !== -1) { var str2 = hoge.substring(10,5,kensaku.length); } ----------------------------- 初心者で恐縮ですが、ご教示の程よろしくお願い致します。

  • JSのクラスについて

    JSのクラスについて https://okwave.jp/qa/q9320085.html の続き >>> >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 Cat.nameとなりCatクラスという箱の中に入っているnameプロパティなのですね。 nameとコンストラクタの引数があるのでthis.nameのnameも引数なのかと思ったのですが、ドットつながりなのでcatクラス(オブジェクト)の中にあるnameプロパティ という事ですね。 関数のスコープの中で宣言する変数のことですよね。 巻き上げが起こる変数ですね。 これとクラス内の変数はほぼ同じ挙動をするという事ですか? するとスコープがクラスにもあるのでしょうか? 巻き上げも >>> >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 thisで別の引数?の物と区別できるという事を伝えたかったのですね。 ただ二つはコンストラクタの引数でthis.nameだけはそもそも引数ではなくプロパティなので、 仮にかぶっても問題ないのでしょうね。 >>> >変数と似ている箱で 変数と違う箱と考えて下さい。 オブジェクト、クラス、関数、変数などいろいろな箱がありこんがらがるのですが、 もしかしてこれらはすべて変数なのですか? つまり箱はすべて変数で、これらは少し個性の違う変数なのでしょうか? >>> >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 クラスをインスタンス化したい場合のみコンストラクタは必要で、 インスタンス化が不要なクラスなら必要ないという事でしょうか? ただクラスはインスタンス化しないと利用できないので、 文法上はコンストラクタなしでも良いが、実際はそのようなことはあり得ないという事でよいでしょうか? またインスタンス化と初期設定の違いが判らないのですが、イコールと考えてよいでしょうか? >>> >入れられないものもあるのですか? クラス内クラスは無理なようです。 それ以外はオブジェクトのように入れられるのですね。 >>> >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 constructor(name) {this.name = name} とは constructor関数の中に中カッコ内の式があり、 catクラス内のnameプロパティにconstructorの引数nameを代入するという事ですよね。 不思議なのはconstructorの引数nameを代入する部分なのですが関数の引数を代入するというのは初めて見ました。 仮引数nameなので constructor(name) { var name = "my cat"; this.name = name } という事ですよね。 つまり下記のcatクラスの引数が実引数になるという事ですよね。 //インスタンス作成 var clsObj = new Cat("my cat"); 関数であれば関数の呼び出しにある引数が実引数として代入されますが、 クラスの場合はconstructor関数の呼び出しにある引数ではなく クラスのインスタンス化にある引数が実引数として代入されるというルールなのですね。 constructor関数の呼び出しがないのが不思議でしたが、 constructor関数は定義するだけで呼び出しはしなくても実行されて、インスタンスを作成するのですね。 そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 >>> 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 こちらも上記の説明で正しいでしょうか? >>> コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 なるほどクラスがナイフの設計図で、constructor、newクラス名がナイフを作るための作業で、 ナイフがインスタンス化されたオブジェクトですが、この時点では何のメリットもないのですね。 インスタンス化されたオブジェクトを使う作業がメソッドという事ですね。 下記例ですとnew Cat("my cat");がナイフを具現化する作業(constructorもこれに当たる?)で、 実際に使うメソッドはここにはないのですかね? class Cat { (name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); >>> 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 上記でも記載した、仮引数と実引数が実質var name = "my cat";というローカル関数と同じ結果になるという意味で書いたのですが、 それでも違うでしょうか? もちろん同じものではないですが、実質同じ結果にはなるのですよね。 >>> そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 下記が同じ結果になるという意味なのでしょうね。 >>> 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ここがよくわからないのですがconstructor(name)のnameは引数ではなくプロパティなのですか? 見た目は引数に見えますが、違いとしてはプロパティは値が入れられる箱であり、 仮引数はローカル変数名でしかなく、ローカル変数そのものではないので、箱ではなく、値を入れられないのですかね?

  • scanfの\nの意味

    タイトルの通りです。 #include<stdio.h> struct Person{ char name[100]; char gender; int age; }; int main(void) { struct Person person1; printf("名前は:"); scanf("%s",person1.name); printf("\n年齢は:"); scanf("%d",&person1.age); printf("\n性別は:"); scanf("\n%c",&person1.gender); printf("\n{name=%s,age=%d,gender=%c}",person1.name,person1.age,person1.gender); return 0; } 上記において aaa , 11 , M と入力すると {name=aaa,age=11,gender=M} と表示されますが、 scanf("\n%c",&person1.gender); を scanf("%c",&person1.gender); に変えると {name=aaa,age=11,gender= } となってしまいます。 この理由と、/nの意味を教えてください。

  • このようなプログラムを教えて下さい

    コマンドプロンプト上の標準入力で文字列と数値を複数組入力していき、 その入力された文字列とそれに対する数値をその数値で比較し最後に大きい順で順に表示するようなプログラムを作りたいのですが、よく構造がわからないので教えて下さい。(ちなみに入力された文字列と数値は、それらを1つのクラスのフィールドとして定義するとして) たとえば人の名前と年齢を入力し大きい順に並べるとか NAME :Bob age :12 NAME :Tom age :25 NAME :Ken age :3 NAME : NAME:Tom,age:25 NAME:Bob,age:12 NAME:Ken,age:3 このように出力したいのですが もしこのようなプログラムを作成することのできる方いましたら、 教えてやってください。

    • ベストアンサー
    • Java
  • C# jsファイルの扱い方

    VS2005 C#を使用しているものです。 javaScriptのみで記述したhtml(BODY内部にスクリプトだけ記述した)をフォーム(ここではform2とします)のwebbrowserで表示するようなものを作ろうとしています。 form2にはスクリプトに渡したい文字列の配列と数値データがあり、別でjsファイルにスクリプトの雛形があるのですが、どのようにして値をform2からjsファイルに渡せばよいのか解らず困っています。 また下記に示したようなことは可能なのでしょうか?  form2でのボタン操作 ↓ jsファイルへ値を代入 ↓ jsファイルのソースをHTMLに埋め込み ↓ そのHTMLをform2のwebbrowserで表示 勉強不足で申し訳ないですが、ご教授願えれば幸いです。

  • node.jsのシェル上で

    コンソール上でnodejsを起動してシェルとしてつかった場合 var x="グローバル変数"; console.log(x); //とするとグローバル変数と出力されます。 さらに console.log(this.x); //とするとグローバル変数と出力されます。 そもそもグローバル変数とはトップレベルコードにおけるオブジェクトのプロパティとあります。 ブラウザだと、トップレベルのスコープで定義した変数は alert(window . variable); でアクセスできます。 ですから、nodeコンソール上で xとっ宣言した変数がthis.xとトップオブジェクトとしてアクセスできることはわかったのですが これをコンソールではなく、jsファイルに描いてそれをnodeコマンドで実行した場合 ~$ node test.js といった具合に実行させた場合 どうも、undefindeと表示されてしまうのです。 これは何が原因でundefinedと出力されてしまうのでしょうか?

  • wordpressでcookie.jsを使う

    wordpressの初心者です。 こちら http://blog.idea-clippin.com/?p=129 の機能をwordpressで作っているサイトに搭載したいと考えています。 jsは別の部分でつかっていて動くので indexと同じ階層にjsフォルダを作りその中にjquery.layerBoard.jsをつっこみ imgフォルダに同じ画像名の画像を。 hederとbodyにコピペをしたのですが、文字しか出なかったのでおそらく欠けているのはcookie.jsと考えています。 cookie.jsを入れれば使えるとおもうのですが、紹介サイトでも省略されていていまいちよくわかりませんでした。 https://github.com/carhartl/jquery-cookieは見てみたもののリンク切れなのかダウンロードボタンはありませんでした。 ワードプレスにcookie.jsを導入するにはどのような方法がありますか?

専門家に質問してみよう