一、定义

  标识符(Identifier)就是一个名字,用来对变量、函数、属性、参数进行命名,或者用做某些循环语句中的跳转位置的标记。

//变量
var Identifier = 123;
//属性
(new Object).Identifier = 'test';
//函数及参数
function IdentifierName(Identifier1){};
//跳转标记
Identifier:
for(var i = 0; i < 5; i++){
if(i == 3){
break Identifier;
}
}

  

二、命名规则

  标识符可以是按照下列格式规则组合起来的一或多个字符:

  • 第一字符必须是一个字母、下划线(_)、或一个美元符号($);
  • 其它字符可以是字母、下划线、美元符号或数字;
//错误示范
6num //开头不能用数字
%sum //开头不能用除(_ $)外特殊符号,如(% + /等)
sum+num //开头中间不能使用除(_ $)外特殊符号,如(% + /等)

  

  javascript是一门区分字母大小写的语言,所以标识符 Identifier 和标识符 identifier 是2个不同的值。

  javascript保留了一些标识符为自己所用,不能把关键字、保留字、true、false和null用作标识符。

//关键字
break do instanceof typeof
case else new var
catch finally return void
continue for switch while
debugger function this with
default if throw
delete in try

//保留字
abstract enum int short
boolean export interface static
byte extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public

//ES6 非严格模式
class enum extends super
const export import

//EW6 严格模式
implements package public
interface private static
let protected yield

  javascript允许标识符中出现 Unicode字符全集中的字母和数字(包括中文)。因此,程序员也可以使用非英语语言或数学符号来书写标识符. 但出于可移植性和易于书写的考虑,通常我们不使用扩展的ASCII或Unicode字符

//不推荐
var 测试文字 = 'test';

三、最佳实践

  1.通常驼峰格式是标识符命名的首选格式,第一个字母小写,剩下的每个单词的首字母大写

var myMoodToday = 'happy';

  2.根据不同的数据类型进行命名

类型                    后缀            示例
数组(Array)       Arr        itemsArr
布尔值(Boolean)    Boo        isCompleteBoo
浮点数(Float)    Fl       priceFl
函数(Function)      Fn      handlerFn
整数(Integer)       Int      itemCountInt
对象(Object)      Obj       dIv1Obj
正则表达式(RegExp) Reg      emailCheckReg
字符串(String)    Str       userNameStr
变量(Variant)       Var       anythingVar

  3.一般来说,变量的命名要使用名词,而函数应该是动词+名称的形式,且尽量要在变量名中体现出值的数据类型。比如,命名count、length和size表明数据类型是数字,而命名name、title和message表明数据类型是字符串。用单个字符命名的变量诸如i、j、k通常在循环中使用

var count = 10;
var myName="xiaohuochai";
var found = true;
function getName(){
return 123;
}

  而对于函数和方法命名来说,第一个单词应该是动词,下面是一些使用动词常见的约定

can    函数返回一个布尔值
has 函数返回一个布尔值
is 函数返回一个布尔值
get 函数返回一个非布尔值
set 函数用来保存一个值

四、同名标识符的优先级

  (1) 流程

    在流程之前,必须写一下标识符是啥. 一句话,就是variable object的属性.而这个对象会被不同执行环境来决定. 比如全局环境下的variable object 就是 global, function code 类型的 执行环境,则是 acitvation object ,而 eval code 内的则是 eval code 所在的 calling context 的 variable object . 当然对于eval code稍微有点说法. 参考:ECMA262 Edition5中 所谓eval code 的 direct call 部分.这里就不细说了. 总之所有标识符都是内部对象 variable object的属性.

    变量初始化流程是这样的:
     词法扫描以后. 把所有标识符找出来, 
     3种标识符:函数名、形参名、变量名, 是分三个阶段初始化的:

     第一步: 初始化函数名,这个过程比较特殊. 因为需要同时创建函数对象, 然后把函数名,作为属性名添加给 variable object ,如果已经存在一个同名的则放弃添加属性名的过程,而直接把创建的函数对象的引用,作为这个属性的值. 如果之前不存在同名属性.则把当前函数名作为属性名,添加给这个variable object .并且对该属性设置 特性集:设置属性无法被delete运算符删除.然后为属性赋值函数对象引用.

     第二步: 形参初始化, 同样的,遇到同名的variable object的属性名,放弃添加属性操作. 如果属性名可用,则添加属性,同时,把undefined赋值给这个属性.并设置特性集,使该属性无法被删除.

     第三步: 变量初始化,与形参初始化一样.

    这里有个例外的初始化过程,发生在 eval code 中.
    eval code中 的变量初始化,不会为calling context 的 variable object 添加属性时,设置 [[DontDelete]]特性.所以可以被delete删除.

    这就是为什么, 表面上看起来,函数名优先级高于形参,而形参又高于变量名的原因.

  (2) 示例

  1. 局部变量先使用后声明,不影响外部同名变量

var x = 1; // --> 外部变量x
function fn(){
alert(x); // --> undefined 局部变量x先使用
var x = 2; // 后声明且赋值
}
fn();
alert(x); // --> 1<br>

  第一个alert:函数fn内第一句输出的x,x是在第二句才定义的,但在编译过程中发生了变量提升,所以alert undefined.

  第二个alert:函数fn内的局部变量x没有影响到外部的变量x。即alert输出是1,不是undefined。

  2. 函数名优先级高于形参(变量提升)

function fn(a){
function a () {
console.log('111')
}
alert(a);
}
fn('hello'); // --> function a () { console.log('111') }

  可以看到函数名和形参同名都是a,输出的是函数a的函数体(a.toString()),却不是字符串"hello"。

  

  3.形参优先级高于只声明却未赋值的局部变量(变量提升)

function fn(a){
var a;
alert(a);
}
fn('hello'); // --> "hello"

  函数fn形参为a,函数内第一句仅声明局部变量a,却并未赋值。从输出结果是"hello"而非undefined可以看出形参a优先级高于仅声明却未赋值的局部变量a。

  4.声明且赋值的局部变量优先级高于形参

function fn(a){
var a = 1;
alert(a);
}
fn('hello'); // --> "1"

  函数fn形参为a,函数内第一句仅声明局部变量a,赋值为1。从输出结果是"1"而非"hello"可以看出声明且赋值的局部变量a优先级高于形参a。

  5.形参优先级高于arguments

function fn(arguments){
alert(arguments);
}
fn('hello'); // --> "hello"<br>

  arguments对象可以直接在函数内使用,是语言本身提供的一个 特殊标识符 。

  这里刚好将形参声明成与其同名。输出可以看到是"hello"而非"[object Object]",即形参arguments覆盖了语言本身提供的真正的arguments。

五、深入了解函数的作用域链及标识符解析过程

 

Javascript 标识符及同名标识符的优先级的更多相关文章

  1. JavaScript作用域,内部函数比参数优先级高

      var x=0; f(); console.log(x); var f=function(){ x=1; } f(); console.log(x); function f(){ x=2; } f ...

  2. 【转载】JavaScript中同名标识符优先级-Snandy

    一,局部变量先使用后声明,不影响外部同名变量 var x = 1; // --> 外部变量x function fn(){ alert(x); // --> undefined 局部变量x ...

  3. Javascript 生成全局唯一标识符 (GUID,UUID)

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...

  4. Javascript生成全局唯一标识符(GUID,UUID)的方法

    方法一 function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { v ...

  5. (4)javascript的运算符以及运算符的优先级

                                    运算符的使用方法 在javascript的程序中要完成各种各样的运算,是离不开运算符的. 在javascript中,按运算符类型可以分为 ...

  6. [JavaScript] 设置函数同名变量为false会导致函数无法执行

    var findEmail=false; function findEmail(){ alert("findEmail");} 这样函数不会运行. 为了保证函数可以运行,修改为: ...

  7. javascript基础语法——变量和标识符

    × 目录 [1]定义 [2]命名规则 [3]声明[4]特性[5]作用域[6]声明提升[7]属性变量 前面的话 关于javascript,第一个比较重要的概念是变量,变量的工作机制是javascript ...

  8. JavaScript 标识符

    JavaScript 标识符 和其他任何编程语言一样,JavaScript 保留了一些标识符为自己所用. JavaScript 同样保留了一些关键字,这些关键字在当前的语言版本中并没有使用,但在以后 ...

  9. JavaScript教程——JavaScript 的基本语法(标识符)

    标识符 标识符(identifier)指的是用来识别各种值的合法名称.最常见的标识符就是变量名,以及后面要提到的函数名.JavaScript 语言的标识符对大小写敏感,所以a和A是两个不同的标识符. ...

随机推荐

  1. Jupyter Notebook中的快捷键

    1.快捷键 Jupyter Notebook 有两种键盘输入模式.编辑模式,允许你往单元中键入代码或文本:这时的单元框线是绿色的.命令模式,键盘输入运行程序命令:这时的单元框线是灰色. 命令模式 (按 ...

  2. CTR预估中GBDT与LR融合方案(转载)

    1.背景 CTR预估,广告点击率(Click-Through Rate Prediction)是互联网计算广告中的关键环节,预估准确性直接影响公司广告收入.CTR预估中用的最多的模型是LR(Logis ...

  3. Arduino-函数库和程序架构介绍

    (1)声明变量及接口的名称 (2)setup().在程序运行时首先要调用setup()函数[初始化函数],用于初始化变量.设置针脚的输出/输入类型.配置串口.引入类库文件等等.每次Arduino上电或 ...

  4. mysql远程连接很慢问题解决

    mysql开启远程访问发现从远程连接每次都在5秒以上,从本机连接很快. 解决方案: [mysqld] 标签下添加一行配置 skip-name-resolve 重启mysqld服务, 问题解决!

  5. Mail.Ru Cup 2018 Round 3 B. Divide Candies

    题目链接 分析一下题意可以得到题目要求的是满足下面这个 公式的不同的i,ji,ji,j的方案数; 即(i2+j2)mod&ThinSpace;&ThinSpace; m=0 (n ≤  ...

  6. ueditor复制文本有多余的空行问题

    今天从ueditor中复制文本,粘贴到记事本中发现每一行后面都多了一个空行. Ueditor中的文本如图: 本来只有三行,全选复制所有内容,再粘贴到记事本中发现有每一行文本后面都有多余的空行: 如果我 ...

  7. Git学习(一):初始化仓库、添加文件、版本回退

    目录 Git学习(一):初始化.添加文件.版本回退 初始化一个仓库 添加文件到Git仓库 版本回退 Git学习(一):初始化.添加文件.版本回退 初始化一个仓库 本文使用的命令行工具为cmder,部分 ...

  8. 医学图像数据(二)——TCIA完整数据集下载方式

    1. 构建下载环境 l  TCIA数据集下载文件为.jnlp格式(JNLP(Java Network Launching Protocol )是java提供的一种可以通过浏览器直接执行java应用程序 ...

  9. Virtual Machine

    之前说到可以使用Assembly language来实现程序编写,把程序通过一个Assembler就可以得到计算机可以操作的二进制文件. 但是Assembly language依旧不适于编程,但怎么将 ...

  10. python使用pip 18以上版本离线安装package

    在内网办公环境,常常需要使用离线安装python的软件包. 一般都会先在互联网的电脑上下载,再拷贝到内网办公机器上进行离线安装. 一般来说,我是这样做的: 1.拷贝和外网电脑上版本一致,且32位或64 ...