杂记—JavaScript梳理(1)

一、基本概念

1、语法

ECMAScript 的语法大量借鉴了 C 及其他类 C 语言(如 Java 和 Perl)的语法。

  • 区分大小写
  • 标识符(标识符,就是指变量、函数、属性的名字,或者函数的参数)
  • 注释
  • 严格模式
  • 语句

2、数据类型

ECMAScript 中有 5 种简单数据类型(也称为基本数据类型): Undefined 、 Null 、 Boolean 、 Number和 String 。还有 1种复杂数据类型—— Object , Object 本质上是由一组无序的名值对组成的。

  • undefined类型
  • null类型
  • boolean类型
  • number类型
  • string类型
  • object类型

其实还有后面ES6的symbol类型

3、操作符

ECMA-262 描述了一组用于操作数据值的操作符,包括算术操作符(如加号和减号)、位操作符、关系操作符和相等操作符。ECMAScript 操作符的与众不同之处在于,它们能够适用于很多值,例如字符串、数字值、布尔值,甚至对象。不过,在应用于对象时,相应的操作符通常都会调用对象的 valueOf()和(或) toString() 方法,以便取得可以操作的值。

  • 一元操作符
  • 位操作符
  • 布尔操作符

4、语句

ECMA-262 规定了一组语句(也称为流控制语句)。从本质上看,语句定义了 ECMAScript 中的主要语法,语句通常使用一或多个关键字来完成给定任务。语句可以很简单,例如通知函数退出;也可以比较复杂,例如指定重复执行某个命令的次数。

  • if语句
  • do-while语句
  • while语句
  • for语句
  • for-in语句
  • break语句和continue语句
  • switch语句

5、函数:

函数对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript 中的函数使用 function 关键字来声明,后跟一组参数以及函数体。
函数的基本语法如下所示:

function functionName(arg0, arg1,...,argN) {
   statements
}

ECMAScript 中的函数在定义时不必指定是否返回值。实际上,任何函数在任何时候都可以通过return 语句后跟要返回的值来实现返回值。
推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。否则,如果函数有时候返回值,有时候有不返回值,会给调试代码带来不便。

理解参数:

引用如下:
ECMAScript 函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript 函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即便你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不会有什么怨言。之所以会这样,原因是 ECMAScript 中的参数在内部是用一个数组来表示的。函数接收
到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过 arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数。
其实, arguments 对象只是与数组类似(它并不是 Array 的实例),因为可以使用方括号语法访问它的每一个元素(即第一个元素是 arguments[0] ,第二个元素是 argumetns[1] ,以此类推),使用 length 属性来确定传递进来多少个参数。在前面的例子中, sayHi() 函数的第一个参数的名字叫
name ,而该参数的值也可以通过访问 arguments[0] 来获取。

注意:
关于参数还要记住最后一点:没有传递值的命名参数将自动被赋予 undefined 值。这就跟定义了变量但又没有初始化一样。

归结以上:
JavaScript 的核心语言特性在 ECMA-262 中是以名为 ECMAScript 的语言的形式来定义的。
也就是说,JavaScript 官方名称是 ECMAscript,而 ECMAscript 的标准是 ECMA-262

引用如下:
JavaScript 的核心语言特性在 ECMA-262 中是以名为 ECMAScript 的伪语言的形式来定义的。
ECMAScript 中包含了所有基本的语法、操作符、数据类型以及完成基本的计算任务所必需的对象,但
没有对取得输入和产生输出的机制作出规定。理解 ECMAScript 及其纷繁复杂的各种细节,是理解其在
Web 浏览器中的实现——JavaScript 的关键。目前大多数实现所遵循的都是 ECMA-262 第 3 版,但很多也已经着手开始实现第 5 版了。以下简要总结了 ECMAScript 中基本的要素。
 ECMAScript 中的基本数据类型包括 Undefined 、 Null 、 Boolean 、 Number 和 String 。
 与其他语言不同,ECMScript 没有为整数和浮点数值分别定义不同的数据类型, Number 类型可
用于表示所有数值。
 ECMAScript 中也有一种复杂的数据类型,即 Object 类型,该类型是这门语言中所有对象的基
础类型。
 严格模式为这门语言中容易出错的地方施加了限制。
 ECMAScript 提供了很多与 C 及其他类 C 语言中相同的基本操作符,包括算术操作符、布尔操作
符、关系操作符、相等操作符及赋值操作符等。
 ECMAScript 从其他语言中借鉴了很多流控制语句,例如 if 语句、 for 语句和 switch 语句等。
ECMAScript 中的函数与其他语言中的函数有诸多不同之处。
 无须指定函数的返回值,因为任何 ECMAScript 函数都可以在任何时候返回任何值。
 实际上,未指定返回值的函数返回的是一个特殊的 undefined 值。
 ECMAScript 中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式
传递的。
 可以向 ECMAScript 函数传递任意数量的参数,并且可以通过 arguments 对象来访问这些参数。
 由于不存在函数签名的特性,ECMAScript 函数不能重载。

二、变量

ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。

在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。之前的 5 种基本数据类型: Undefined 、 Null 、 Boolean 、 Number 和 String 。这 5 种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。

引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript 不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的。

1、变量值的复制:
1、如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制
到为新变量分配的位置上。
在这里插入图片描述

在此, num1 中保存的值是 5。当使用 num1 的值来初始化 num2 时, num2 中也保存了值 5。但 num2中的 5 与 num1 中的 5 是完全独立的,该值只是 num1 中 5 的一个副本。此后,这两个变量可以参与任何操作而不会相互影响。

2、当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到
为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一
个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另
一个变量

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "fqniu";
alert(obj2.name); //"fqniu"

首先,变量 obj1 保存了一个对象的新实例。然后,这个值被复制到了 obj2 中;换句话说, obj1
和 obj2 都指向同一个对象。这样,当为 obj1 添加 name 属性后,可以通过 obj2 来访问这个属性,
因为这两个变量引用的都是同一个对象。

在这里插入图片描述
2、传递参数:

ECMAScript 中所有函数的参数都是按值传递的。

function setName(obj) {
  obj.name = "fqniu";
}
var person = new Object();
setName(person);
alert(person.name); //"fqniu"

以上代码中创建一个对象,并将其保存在了变量 person 中。然后,这个变量被传递到 setName()
函数中之后就被复制给了 obj 。在这个函数内部, obj 和 person 引用的是同一个对象。换句话说,即
使这个变量是按值传递的, obj 也会按引用来访问同一个对象。于是,当在函数内部为 obj 添加 name
属性后,函数外部的 person 也将有所反映;因为 person 指向的对象在堆内存中只有一个,而且是全
局对象。

function setName(obj) {
obj.name = "fqniu";
obj = new Object(); 
obj.name = "hello fqniu";
}
var person = new Object();
setName(person);
alert(person.name); //"fqniu"

这个例子与前一个例子的唯一区别,就是在 setName() 函数中添加了两行代码:一行代码为 obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的 name 属性。在把 person 传递给setName() 后,其 name 属性被设置为 “fqniu” 。然后,又将一个新对象赋给变量 obj ,同时将其 name属性设置为 “hello fqniu” 。
如果 person 是按引用传递的,那么 person 就会自动被修改为指向其 name 属性值为 “hello fqniu” 的新对象。但是,当接下来再访问 person.name 时,显示的值仍然是 “fqniu” 。
这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
可以这样理解:在函数里面的两个obj是两个不同的东西,算是互不影响

3、检测类型:
要检测一个变量是不是基本数据类型?用 typeof 操作符是最佳的工具。说得更具体一点, typeof 操作符是确定一个变量是字符串、数值、布尔值,还是 undefined 的最佳工具。如果变量的值是一个对象或 null ,则 typeof 操作符会返回 “object” 。
我们并不是想知道某个值是对象,而是想知道它是什么类型的对象。为此,ECMAScript提供instanceof 操作符,其语法如下所示:

result = variable instanceof constructor

根据规定,所有引用类型的值都是 Object 的实例。因此,在检测一个引用类型值和 Object 构造函数时, instanceof 操作符始终会返回 true 。当然,如果使用 instanceof 操作符检测基本类型的值,则该操作符始终会返回 false ,因为基本类型不是对象。

三、引用类型

  • Object类型
    创建 Object 实例的方式有两种。第一种是使用 new 操作符后跟 Object 构造函数,第二种方式是使用对象字面量表示法。对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。
var person = new Object();
person.name = "fqniu";
person.age = 25;

var person = {
   name : "fqniu",
   age : 25
};
  • Array类型
    创建数组的基本方式有两种。第一种是使用 Array 构造函数,第二种基本方式是使用数组字面量表示法。数组字面量由一对包含数组项的方括号表示,多个数组项之间以逗号隔开
var colors = new Array();
var colors = new Array("red", "blue", "green");

var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组

数组方法很多,可以看之前的博客内容JavaScript数组、字符串回顾

  • Date类型
    创建一个日期对象,使用 new 操作符和 Date 构造函数
var now = new Date();

这里也不过多解释。。。

  • RegExp类型
    ECMAScript 通过 RegExp 类型来支持正则表达式。使用下面类似 Perl 的语法,就可以创建一个正
    则表达式。
var expression = / pattern / flags ;

其中的模式(pattern)部分可以是任何简单或复杂的正则表达式,可以包含字符类、限定符、分组、
向前查找以及反向引用。每个正则表达式都可带有一或多个标志(flags),用以标明正则表达式的行为。
正则表达式的匹配模式支持下列 3 个标志。
 g :表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即
停止;
 i :表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写;
 m :表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模
式匹配的项。
因此,一个正则表达式就是一个模式与上述 3 个标志的组合体。不同组合产生不同结果

  • Function类型
    函数实际上是对象,每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。函数通常是使用函数声明语法定义的。
function sum (num1, num2) {
   return num1 + num2;
}

var sum = function(num1, num2){
   return num1 + num2;
};

这里也不过多解释。。。

  • 基本包装类型
    • 1、Boolean类型( Boolean 对象在 ECMAScript 中的用处不大,不过多解释)
    • 2、Number类型
      Number 是与数字值对应的引用类型。要创建 Number 对象,可以在调用 Number 构造函数时向其中传递相应的数值。
    • 3、String类型
      String 类型是字符串的对象包装类型,可以像下面这样使用 String 构造函数来创建。
//2、Number类型
var numberObject = new Number(10);
//案例如下
var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
//3、String类型
var stringObject = new String("hello world");

字符串方法很多,可以看之前的博客JavaScript数组、字符串回顾

  • 单体内置对象
    • 1、Global对象
      Global (全局)对象可以说是 ECMAScript 中最特别的一个对象,所有在全局作用域中定义的属性和函数,都是 Global 对象的属性;诸如 isNaN() 、 isFinite() 、 parseInt() 以及 parseFloat() ,实际上全都是 Global对象的方法。除此之外, Global 对象还包含其他一些方法。
      比如:

      • URI 编码方法(Global 对象的 encodeURI() 和 encodeURIComponent() 方法可以对 URI(Uniform ResourceIdentifiers,通用资源标识符)进行编码,以便发送给浏览器。有效的 URI 中不能包含某些字符,例如空格。而这两个 URI 编码方法就可以对 URI 进行编码,它们用特殊的 UTF-8 编码替换所有无效的字符,从而让浏览器能够接受和理解。)
      • eval() 方法 ( 整个 ECMAScript语言中最强大的一个方法: eval() ,这个方法就像是一个完整的 ECMAScript 解析器,它只接受一个参数,即要执行的 ECMAScript (或 JavaScript)字符串。)
      • window 对象(ECMAScript 虽然没有指出如何直接访问 Global 对象,但 Web 浏览器都是将这个全局对象作为window 对象的一部分加以实现的。因此,在全局作用域中声明的所有变量和函数,就都成为了 window对象的属性。)
    • 2、Math对象
      ECMAScript 还为保存数学公式和信息提供了一个公共位置,即 Math 对象。与我们在 JavaScript 直接编写的计算功能相比, Math 对象提供的计算功能执行起来要快得多。 Math 对象中还提供了辅助完成这些计算的属性和方法,Math 对象还包含许多方法,用于辅助完成简单和复杂的数学计算。
      比如:

      • Math.min()Math.max() 方法
      • Math.random() 方法返回大于等于 0 小于 1 的一个随机数
      • Math.ceil() 执行向上舍入,即它总是将数值向上舍入为最接近的整数;
      • Math.floor() 执行向下舍入,即它总是将数值向下舍入为最接近的整数;
      • Math.round() 执行标准舍入,即它总是将数值四舍五入为最接近的整数

补充创建对象

   //1、利用字面量 创建对象
    var obj={
        uname:'小白',
        age:18,
        sex:'男',
        sayhi:function (){
            console.log('hi');
            
        }
    }
    console.log(obj.uname); //访问对象属性时使用的都是点表示法
    console.log(obj['age']); //也可以使用方括号表示法来访问对象的属性
    /*
    从功能上看,这两种访问对象属性的方法没有任何区别。但方括号语法的主要优点是可以通过变量来访问属性,例如:
    var propertyName = "uname";
    console.log(person[propertyName]); //小白

    如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法。例如:
    person["first name"] = "小白";
    由于 "first name" 中包含一个空格,所以不能使用点表示法来访问它。然而,属性名中是可以包含非字母非数字的,
    这时候就可以使用方括号表示法来访问它们,通常,除非必须使用变量来访问属性,否则我们建议使用点表示法。
    */
    obj.sayhi();


    //2、利用new object 创建对象
    function createPerson(name, age, job){
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            console.log(this.name);
        };
        return o;
    }
    var person1 = createPerson("张三疯", 99, "CEO");
    var person2 = createPerson("张无忌", 37, "CFO");
    console.log(person1);
    console.log(person2);


    //3、利用构造函数 创建对象
    function Person(name, age, sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.sayName = function(){
            console.log(this.name);
        };
    }
    var person3 = new Person("杨过", 29, "男");
    var person4 = new Person("小龙女", 27, "女");
    console.log(person3);
    console.log(person4);

    // 当作构造函数使用
    var person = new Person("杨过", 29, "男");
    person.sayName(); //杨过
    // 作为普通函数调用
    Person("小龙女", 27, "女"); // 添加到 window
    window.sayName(); //小龙女
    // 在另一个对象的作用域中调用
    var o = new Object();
    Person.call(o, "旺财", 25, "男");
    o.sayName(); //旺财
    /*
    这个例子中的前两行代码展示了构造函数的典型用法,即使用 new 操作符来创建一个新对象。接下
    来的两行代码展示了不使用 new 操作符调用 Person() 会出现什么结果:属性和方法都被添加给 window
    对象了。当在全局作用域中调用一个函数时, this 对象总是指向 Global 对象(在浏览器中就是 window 对象)。
    因此,在调用完函数之后,可以通过 window 对象来调用 sayName() 方法,并且还返回了 "小龙女" 。
    最后,也可以使用 call() (或者 apply() )在某个特殊对象的作用域中 调用 Person() 函数。
    这里是在对象 o 的作用域中调用的,因此调用后 o 就拥有了所有属性和 sayName()方法。
    */

构造函数注意点:
    1、构造函数名字首字母必须大写;
    2、构造函数不需要return 就可以结果
    3、调用构造函数必须使用new
    4、只要new XXX()  调用函数就创建一个对象 XXX
    5、属性和方法前面必须加this

要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4个步骤:
    1、构造函数可以在内存中创建一个空的对象
    2、this会指向刚才的空对象
    3、执行前面的构造函数里面的代码给这个空对象添加属性和方法
    4、返回这个对象(构造函数里面不需要return)

以上大部分内容都是看书(Javascript高级程序设计)总结记录,仅用于个人学习!

继续更新中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值