浅谈JavaScript中的string拥有方法的原因


Posted in Javascript onAugust 28, 2015

引子

我们都知道,JavaScript数据类型分两大类,基本类型(或者称原始类型)和引用类型。

基本类型的值是保存在栈内存中的简单数据段,它们是按值访问的。JS中有五种基本类型:Undefined、Null、Boolean、Number和String。

引用类型的值是保存在堆内存中的对象,它的值是按引用访问的。引用类型主要有Object、Array、Function、RegExp、Date。

对象是拥有属性和方法的,所以我们看到下面这段代码一点也不奇怪.

var favs=['鸡蛋','莲蓬'];
favs.push('秋葵');
console.log(favs);//["鸡蛋", "莲蓬", "秋葵"]
console.log(favs.length);//3

Array是引用类型,所以它自然可以拥有属性(length)和方法(push),这天经地义地就像夏天一定要吃冰淇淋一样。但是,再看下面的代码,仔细想想,这这这,合法吗?

var realMessage="Said I love you but I lied";
var myMessage=realMessage.substring(5,15);
console.log(myMessage); //"I love you"

有一个心碎的女纸任性地对一个用来分手的字符串任性地执行了“substring”方法,然后开心地看着剪辑版睡过去了。可是可是可是,不是说string是基本类型吗,为什么它可以拥有方法??还有没有王法啊青天大老爷!

其实,这一切,都是因为有个叫“基本包装类型”的东东。这个基本包装类型特别耿直,是真正的“事了拂衣去,深藏功与名”!

基本包装类型

除了一开始提到的Object、Array等引用类型,JavaScript还为我们提供了三种特殊的引用类型:String、Number和Boolean,方便我们操作对应的基本类型。

继续看上面的剪辑字符串的例子,有没有注意到,尽管使用了substring方法,realMessage本身的值是不会变的,调用这个方法只是返回了一个新的字符串。

这就是基本包装类型的作用了。本来你是没有方法的,但是你想用方法的时候,你尽管调,对应的基本包装类型有这个方法就行。例如上面的substring方法,string这个基本类型是不可能有这个方法的,但是String这个包装类型有啊,它会吭吭哧哧地把这个方法执行完把结果返回。在执行到:

realMessage.substring(5,15)

这行代码时,发生了很多事。

首先,它会从内存中读取realMessage的值。当处于这种读取模式下的时候,后台就开始干活了。JS高程是这样描述后台完成的这些动作的:

1.创建String类型的一个实例;
2.在实例上调用指定的方法;
3.销毁这个实例

上面的例子可以用这样的代码来说明:

var _realMessage=new String("Said I love you but I lied");
var myMessage=_realMessage.substring(5,15);
_realMessgae=null; //方法调用后即销毁

所以,这样我们就明白了,并不是基本类型string执行了自身方法,而是后台为它创建了一个对应的基本包装类型String,它根据基本类型的值实例化出了一个实例,让这个实例去调用指定方法,最后销毁自己,感天动地有木有。

注意最后一步基本包装类型“会销毁”的特性,这决定了我们不能为基本类型值添加自定义属性和方法。

var me="sunjing";
me.age=18;
console.log(me.age);//undefined

我给“me“这个字符串添加了age属性,值设为美好的18岁,然并卵,再次访问时,这个属性已经渺无踪迹了。这是因为:

执行到第二行代码属性赋值时,后台创建了一个基本包装类型的实例,这个age属性确实挂到实例上去了,但是紧跟着,这个实例就被销毁了。执行到第三行时,又重新创建了新的基本包装类型的实例,自然是没有age属性的。

显示使用基本包装类型

除了在字符串处于读取模式下,后台会帮我们创建基本包装类型实例时,我们自己也可以显示地创建。

var str=new String("hello");
var str2=str.toUpperCase();
console.log(str2);//"HELLO:

这样与后台帮我们创建时变量中保存的东西是不同的。

var str1=new String("hello");
var str2="hello";
typeof str1 //"object"
typeof str2 //"string"

总结

多亏了有基本包装类型,我们操作string、boolean、number这三种基本类型更方便了。每当读取这三种基本类型值时,后台会创建对应的包装类型实例,这个实例会调用指定方法,调用完会被销毁。这种短暂的生命周期决定了我们不能为基本类型添加自定义的属性和方法。

我们再来看下javascript中String类的subString()方法和slice()方法

最近在看《Javascript高级程序设计》一书,在书中发现一些以前没有接触过的且比较实用的技巧和知识点,想通过博客记录一下,以加深记忆。

在该书2.8.4节中讲到String类中的subString()方法和slice()方法,其用法和返回结果都基本相同,如下示例:

var strObj = new String("hello world");
alert(strObj.slice(3));    // 输出结果:"ol world"
alert(strObj.subString(3));  
// 输出结果:"ol world"
alert(strObj.slice(3, 7));    // 输出结果:"lo w"
alert(strObj.subString(3,7));   // 输出结果:"lo w"

由以上代码的输出结果可已看出,slice()方法和subString()方调用方法法和输出结果完全一样,这两种方法返回的都是要处理的字符串的子串,都接受一个或两个参数,第一个参数是要获取的子串的起始位置,第二个参数是要获取子串的终止位置,如果第二个参数省略终止位置就默认为字符串的长度,且两个方法都不改变String对象自身的值。

为什么有两个功能完全相同的方法呢?事实上,这两个方法并不完全相同,不过只在参数为负值时,他们处理参数的方式稍有不同。

对于负数参数,slice()方法会用字符串的长度加上参数,subString()方法将其作为0处理,例如:

var strObj = new String("hello world");
alert(strObj.slice(-3));

// 输出结果:"rld"
alert(strObj.subString(-3));
  // 输出结果:"hello world"
alert(strObj.slice(3,-4));

 // 输出结果:"lo w"
alert(strObj.subString(3,-4))
 // 输出结果:"hel"

这样既可看到slice()和subString()方法的主要不同。当只有参数-3时,slice()返回"rld",subString()则返回"hello world"。这是因为对于字符串"hello world",slice(-3)将被转换成slice(8),而subString(-3)则转化成subString(0)。同样,使用3和-4差别也是很明显。slice()方法将被转换成slice(3,7),与前面的例子相同,返回"lo w"。而subString()方法则将这个两个参数解释为subString(0,3),实际上是:subString(0,3),因为subString()总是把较小的参数作为起始位,较大的数字最为终止位。

Javascript 相关文章推荐
JavaScript splice()方法详解
Sep 22 Javascript
JavaScript中的操作符类型转换示例总结
May 30 Javascript
javascript将中国数字格式转换成欧式数字格式的简单实例
Aug 02 Javascript
浅谈js中字符和数组一些基本算法题
Aug 15 Javascript
D3.js封装文本实现自动换行和旋转平移等功能
Oct 14 Javascript
bootstrap table实例详解
Jan 06 Javascript
jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例
Aug 04 jQuery
js移动端图片压缩上传功能
Aug 18 Javascript
旺旺在线客服代码 旺旺客服代码生成器
Jan 09 Javascript
微信小程序时间选择插件使用详解
Dec 28 Javascript
微信小程序实现多选框全选与取消全选功能示例
May 14 Javascript
使用vue cli4.x搭建vue项目的过程详解
May 08 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
Aug 27 #Javascript
jquery实现左右滑动菜单效果代码
Aug 27 #Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 #Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
Aug 27 #Javascript
jquery图片倾斜层叠切换特效代码分享
Aug 27 #Javascript
JavaScript实现非常简单实用的下拉菜单效果
Aug 27 #Javascript
JavaScript中的Function函数
Aug 27 #Javascript
You might like
浅析memcache启动以及telnet命令详解
2013/06/28 PHP
解决PHP mysql_query执行超时(Fatal error: Maximum execution time …)
2013/07/03 PHP
php获取字符串中各个字符出现次数的方法
2015/02/23 PHP
分享php分页的功能模块
2015/06/16 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
php和C#的yield迭代器实现方法对比分析
2019/07/17 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)
2011/03/25 Javascript
当前页禁止复制粘贴截屏代码小集
2013/07/24 Javascript
jquery 页眉单行信息滚动显示实现思路及代码
2014/06/26 Javascript
JQuery中使用ajax传输超大数据的解决方法
2014/07/14 Javascript
jQuery DOM插入节点操作指南
2015/03/03 Javascript
JavaScript来实现打开链接页面的简单实例
2016/06/02 Javascript
javascript类型系统——日期Date对象全面了解
2016/07/13 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
浅谈vue-router2路由参数注意的问题
2017/11/08 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
让Vue响应Map或Set的变化操作
2020/11/11 Javascript
python构造icmp echo请求和实现网络探测器功能代码分享
2014/01/10 Python
Python判断变量是否已经定义的方法
2014/08/18 Python
Python计算三角函数之asin()方法的使用
2015/05/15 Python
Python基于回溯法解决01背包问题实例
2017/12/06 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
Python基础之循环语句用法示例【for、while循环】
2019/03/23 Python
python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析
2019/10/14 Python
详解python opencv、scikit-image和PIL图像处理库比较
2019/12/26 Python
Django xadmin安装及使用详解
2020/10/26 Python
CSS3 3D立方体效果示例-transform也不过如此
2016/12/05 HTML / CSS
H5页面适配iPhoneX(就是那么简单)
2019/12/02 HTML / CSS
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
Penhaligon’s英国官网:成立于1870年的英国香水制造商
2021/02/18 全球购物
高一地理教学反思
2014/01/18 职场文书
办公室主任竞聘演讲稿
2014/05/15 职场文书
2014财务人员自我评价范文
2014/09/21 职场文书
采购员工作总结范文
2015/08/12 职场文书
会计做账心得体会
2016/01/22 职场文书