一、前言

放了个元旦,休息了三天,加上春运抢票一系列事情的冲击,我感觉我的心已经飞了。确实应该收收心,之前计划的学习任务也严重脱节了;我恨不得打死我自己。

在上篇博客中,笔记记录到了关于构造函数方面的一些写法和用法,这篇博客,会从原书中数组直接量开始,自己读了下之前的博客,还是有点照搬概念的意思,想了下,还是得简化概念,按照自己的思路去写,那么开始。

二、数组直接量

概要:创建数组的两种方式,Array()创建的隐性问题

在JS中,数组也是对象,我们可以通过内置构造函数Array()创建数组,也可以通过直接量方式创建。

使用Array()创建:

var arr = new Array('echo', '时间跳跃', "听风是风");

数组直接量创建:

var arr = ['echo', '时间跳跃', "听风是风"];

很明显,直接量的写法更为简单,所以在实际开发中,对于创建数组,是绝对推荐直接量写法。

为什么不推荐new Array()的写法呢,因为当我们为Array构造器传入一个数字,这个数字不会成为数组的元素,而是成了设置数组的length。

var arr = new Array(3);
console.dir(arr[0]);//undefined

我们知道,数组的length是不存在浮点数的,当我们为Array()中设置一个浮点数时会直接导致错误。

var arr = new Array(3.14);//报错

三、判断是不是数组

概括:判断是不是数组的几种方式

判断是不是数组,是不是对象,首先想到的是typeof,但是很遗憾,typeof的判断较为粗糙,得到的只是object的结果。

var arr = [1,2,3];
typeof arr;//object

在ES5中提供了一个好用的数组检验方法Array.isArray(),它返回一个布尔值,如果你检验的对象是一个数组,它将返回true。

var arr = [1,2,3];
Array.isArray(arr);//true

但如果你的开发环境不支持ES5,最保险的做法就是使用Object.prototype.toString()方法来达到检验目的。

var arr = [1,2,3];
Object.prototype.toString.call(arr) === '[object Array]'//true

 四、正则表达式直接量

概括:正则创建的2种方式,使用RegExp构造函数创建的情景

在js中正则表达式也是对象,可以通过正则直接量与RegExp()构造函数两种方式创建:

创建正则匹配一个字母a,使用直接量:

var re = /a/gm

使用构造函数创建:

var re = new RegExp('a','gm');

与构造函数写法相比,正则表达式直接量使用两个斜线包裹起来,正则匹配的主体部分不包括两端的斜线,修饰符gm不需要使用引号。

假设我们需要匹配一个斜线\,两者写法区别如下:

var re = /\\/gm
//构造函数
var re = new RegExp('\\\\','gm');

在直接量中我们使用\对\进行转译,而在构造函数写法中,转译两次的行为导致使用了四个\,很明显对于阅读来说增加了复杂性。

js中提供了三个修饰符,且修饰符顺序随意:

g:全局匹配

m:多行匹配

i:忽略大小写

虽然推荐直接量的方式创建正则,但如果你创建的正则包含变量,则不得不使用构造函数创建。

const str = "abc";
const re = new RegExp(str, 'gm');

比较有趣的是,在使用构造函数创建正则时,不带new调用RegExp()和带new调用的结果是完全一样的。这与我在上篇文章中说不带new调用对象指向window有些不同。

其实写到这里,原书中第三章基本介绍完了,第四章开始介绍函数,这一章主要介绍函数几种声明方式,函数提前,以及一些模式,性能优化等。上面篇幅感觉有点少,顺带把第四章记录一点。

五、函数基础概念

概括:函数的一些特性

JS中的函数也是对象,且函数有两个主要的特性,第一,函数是一等对象(一等公民),第二是函数提供作用域支持。

函数的第一特性函数是对象,所以我们可以对函数做以下操作

1.在程序执行时动态创建函数。

2.可以将函数作为值赋予给一个变量,可以将函数的引用拷贝到另一个变量。

3.可以将函数作为参数传入到另一函数,也能作为函数返回值。

3.函数可以拥有自己的属性和方法。

当我们通过构造函数的形式来创建一个函数,很明显,这个函数属于构造器的一个实例,属于一个对象。

const func1 = new Function('a', 'b', 'return a+b');
func1(1,2);//

这里func1就是一个对象,但和前面创建各类对象,字符串,正则一样,并不推荐构造器的形式创建,一是可读性差,其次执行代码块return a + b本质上属于一段字符串,在执行时也做了类似于eval()的操作。

函数的第二个特性是可以提供作用域,js中原本是没有块级作用域概念的(现在let可以声明块级作用域),也就是不能通过花括号来创建作用域,而创建一个函数,则会生成一个独立的作用域。

在函数体内凡是通过var声明的变量(let const都一样,毕竟书有点老)相对函数而言,都是局部作用域,在函数外是不可见的。

需要注意的是,虽然说花括号提供作用域,但是对于if while for这一类的花括号,在里面通过var创建的变量也不是局部作用域,除非外层有函数,否则就是一个全局变量。(有个疑问,如果if里面使用let const声明,外面依旧读不到,我暂时没了解,查阅了补全此问题)

if(true){
var a = 1
};
console.log(a);// function func1() {
var b = 1
};
console.log(b);//报错

六、函数术语与函数的几种创建方式

概括:什么是函数表达式,什么是函数声明?函数name属性与函数声明提前

我们可以通过构造函数,函数表达式,函数声明三种形式来创建一个函数。构造函数的创建方式在上面已有举例,记住,不推荐这种写法。

通过函数表达式创建函数:

//带有命名的函数表达式
var func1 = function func(a, b){
return a +b;
};
func1(1,2)//
func1.name;//func //匿名函数表达式
var func2 = function (a, b){
return a +b;
};
func2(1,2);
func2.name;//func2

上述代码中函数一的name属性为func,但是调用它使用的是func1(),函数二虽然匿名,但依然可以找到name属性,是我们赋予的变量名func2。

两种函数作用完全相同,调用均为使用函数赋予的变量名进行调用,我个人在表达式创建上常用匿名表达式的写法。

通过函数声明创建函数:

function add(a, b){
return a + b;
};
add(1,2)//

可以说函数声明与带有命名的函数表达式的区别就是有没有将这个函数赋予给一个变量。

我们在前面的创建对象,字符串,正则时都有提到一个直接量创建的概念,其实函数也有'函数直接量的说法',它对应的就是函数表达式,但这个术语有歧义的,所以不推荐这么称呼它;但如果有人说函数直接量,你还是得知道对方说的是函数表达式的创建方式,这里顺带提一下。

函数声明提前:

关于函数声明与函数表达式的使用取舍,一般推荐在全局,或者函数体内创建函数时,使用函数声明的写法;因为函数声明是存在函数提升的,在全局作用域创建后,你可以在任意一个地方调用它。

同样全局作用域,使用函数表达式创建的函数,你只能在创建之后调用,因为函数表达式提升是被赋予的变量,函数赋值的操作停留在原地,所以在创建前调用函数会报错,这是也两者的区别所在。

//函数声明,创建一次,随处可用
add(1,2);//
function add(a, b){
return a + b;
};
add(1,2);// //函数表达式,只能在创建后使用
func(a,b);//报错
var func = function (a, b){
return a + b;
};
func(1,2);//
//上述代码等同于
var func;
func(a,b)//此时func并不是一个函数,报错。
func = function (a, b){
return a + b;
};
func(1,2);//

函数name属性:

原书中提到,匿名函数表达式的name属性在火狐,safari中为'',也就是没有赋予具体的值,在IE中是无定义的。我本人测试name属性是被赋予的变量名,我的浏览器是谷歌,可能是因为浏览器版本的不同,对此差异简单提一下。

最后强调一下JS函数两大特性,函数是对象,函数提供局部变量作用域。

先记到这里吧。下一篇将从函数回调模式开始说起。

精读JavaScript模式(四),数组,对象与函数的几种创建方式的更多相关文章

  1. 精读JavaScript模式(五),函数的回调、闭包与重写模式

    一.前言 今天地铁上,看到很多拖着行李箱的路人,想回家了. 在上篇博客结尾,记录到了函数的几种创建方式,简单说了下创建差异,以及不同浏览器对于name属性的支持,这篇博客将从第四章函数的回调模式说起. ...

  2. 面向面试编程——javascript对象的几种创建方式

    javascript对象的几种创建方式 总共有以下几个模式: 1.工厂模式 2.构造函数模式 3.原型模式 4.混合构造函数和原型模式 5.动态原型模式 6.寄生构造函数模式 7.稳妥构造函数模式 1 ...

  3. Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式。

    原文:Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式. Android Activity 的四种启动模 ...

  4. JavaScript 闭包的详细分享(三种创建方式)(附小实例)

    JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...

  5. 多对多的三种创建方式-forms相关组件-钩子函数-cookie与session

    多对多的三种创建方式 1.全自动(推荐使用的**) 优势:第三张可以任意的扩展字段 缺点:ORM查询不方便,如果后续字段增加更改时不便添加修改 manyToManyField创建的第三张表属于虚拟的, ...

  6. UICollectionView基础/UICollectionViewCell的四种创建方式

    前言 UICollectionViewCell的四种创建方式:http://blog.csdn.net/ZC_Huang/article/details/52002302 这个控件,看起来与UITab ...

  7. 精读JavaScript模式(六),Memoization模式与函数柯里化的应用

    假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的 ...

  8. 精读JavaScript模式(二)

    我在想知识点怎么去分类,原本计划一章节一篇,但这样会会显得长短不一.更主要的是看到哪写的哪更为随意.那么这一篇还是紧接第一篇进行知识梳理,上篇说到了更优化的for循环,现在继续聊聊其它的循环方式. 1 ...

  9. 精读JavaScript模式(七),命名空间模式,私有成员与静态成员

    一.前言 惰性十足,这篇2月19号就开始写了,拖到了现在,就是不愿意花时间把看过的东西整理一下,其它的任何事都比写博客要有吸引力,我要反省自己. 从这篇开始,是关于JS对象创建模式的探讨,JS语言简单 ...

随机推荐

  1. 设计模式 策略模式2 c++11

    根据需求的不同 选择不同的策略算法 之前是保存的各种策略类的指针 这里直接使用 function  bind 选择对应的算法 代码 // 005.cpp: 定义控制台应用程序的入口点. // #inc ...

  2. SprirngBoot微服务之间的交互—— restTemplate

    一 例:需要在storage服务中请求utils服务的某个接口(两个服务都已向同一台eureka server 注册) 步骤: 1 在utils创建需被调用的接口 @RestController @R ...

  3. ios 单例的再次理解

    单例模式    在建模的时候,如果这个东西确实只需要一个对象,多余的对象都是无意义的,那么就考虑用单例模式.比如定位管理(CLLocationManager),硬件设备就只有一  个,弄再多的逻辑对象 ...

  4. BeanUtil拷贝

    拷贝vo对象 一些查询到的数据很多是不需要的,可以创建vo对象,对需要的对象属性进行拷贝 maven依赖 <dependency> <groupId>org.projectlo ...

  5. [GO]简单的http服务器和客户端的实现

    package main import ( "net/http" "fmt" ) func Hello(w http.ResponseWriter, r *ht ...

  6. tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  7. Ubuntu 安装 chrome浏览器

    按下 Ctrl + Alt + t 键盘组合键,启动终端. 输入以下命令: sudo wget http://www.linuxidc.com/files/repo/google-chrome.lis ...

  8. kaldi脚本注释二

    steps/decode.sh #!/bin/bash # Copyright 2012 Johns Hopkins University (Author: Daniel Povey) # Apach ...

  9. Python自动化编程-树莓派GPIO编程(二)

    树莓派我们编程一般都直接用高效的python,针对于GPIO编程,python也是有这一方面的库的,这里最有名也是最常用的就是RPI.GPIO了.这个库是专门为树莓派GPIO编程所设计的,利用它你可以 ...

  10. Linux 查看IP

    UBuntu 系统下 按Ctrl+Alt+T 唤出终端 在终端输入: ifconfig 命令 点击回车 就可以看到自己电脑在局域网的IP地址了 图中第二行 inet 地址:192.168.1.101 ...