js中什么叫原生js包装类型

javascript是个入门门槛很低的语言,甚至一个从来没有接触过javascript的技术人员,几小时内就可以写出一个简单有用的程序代码。
但是如果因此你就下结论:javascript是门简单的语言。那你就大错特错了。想写出高性能的代码,同样需要具备一个高级程序员的基本素养。
一个java或者c++程序员,不一定能写出高性能的javascript代码,但更容易写出高性能的javascript代码。
javascript的简单是基于它&胸襟广阔&的包容性。它声明时,不需要指定类型,甚至可以任意的转换类型。它面向对象,却没有类(Class)的限制。它是一门崇尚自由又非常严谨的语言,如果你是一个自由主义者,那么,拥抱javascript吧!
面向对象编程 (OOP) 是一种流行的编程方法。但javascript的OOP,较之JAVA、c++有很大的同,主要体现它的继承方式不同。javascript是基于原型PROTOTYPE继承的。所有对象都是基于原型链,最终追述到Object对象。
这里不想讨论过多的关于javascript的继承方式和其它语言的继承方式的不同之处。主要讨论如何封装javascript的Class,以便更好的管理和维护基础代码,减少重复代码,以及更好的模块化编程。
下面是几个github上找到的比较好的Class封装类库:
& 一、MY-CLASS&
& 项目地址:/jiem/my-class
先看基本用法:
a、新建一个类
(function() {
var Person = my.Class({
// 添加静态方法
AGE_OF_MAJORITY: 18
// 构造函数
constructor: function(name, age) {
this.name =
this.age =
// 实例方法
sayHello: function() {
console.log('Hello from ' + this.name + '!');
// 实例方法
drinkAlcohol: function() {
this.age & Person.AGE_OF_MAJORITY ?
console.log('Too young! Drink milk instead!') :
console.log('Whiskey or beer?');
// 暴露给命名空间
myLib.Person = P
var john = new myLib.Person('John', 16);
john.sayHello(); //log "Hello from John!"
john.drinkAlcohol(); //log "Too young! Drink milk instead!"
b、继承一个类
(function() {
//Dreamer 继承 Person
var Dreamer = my.Class(Person, {
// 构造方法
constructor: function(name, age, dream) {
Dreamer.Super.call(this, name, age);
this.dream =
// 实例方法
sayHello: function() {
superSayHello.call(this);
console.log('I dream of ' + this.dream + '!');
// 实例方法
wakeUp: function() {
console.log('Wake up!');
// Super访问父类
var superSayHello = Dreamer.Super.prototype.sayH
// 暴露给全局命名空间
myLib.Dreamer = D
var sylvester = new myLib.Dreamer('Sylvester', 30, 'eating Tweety');
sylvester.sayHello(); //log "Hello from Sylvester! I dream of eating Tweety!"
sylvester.wakeUp(); //log "Wake up!"
c、给类添加新方法
// 给myLib.Dreamer添加新方法
my.extendClass(myLib.Dreamer, {
// 添加静态方法
STATIC : {
s_dongSomeThing : function(){
console.log("do some thing!");
// 添加实例方法
touchTheSky: function() {
console.log('Touching the sky');
// 添加实例方法
reachTheStars: function() {
console.log('She is so pretty!');
&d、实现一个类的方法
// 声明一个新类
myLib.ImaginaryTraveler = my.Class({
travel: function() { console.log('Traveling on a carpet!'); },
crossOceans: function() { console.log('Saying hi to Moby Dick!'); }
(function() {
//Dreamer 继承 Person 实现 ImaginaryTraveler的方法
var Dreamer = my.Class(Person, ImaginaryTraveler, {
// 构造方法
constructor: function(name, age, dream) {
Dreamer.Super.call(this, name, age);
this.dream =
// 暴露给全局命名空间
myLib.Dreamer = D
var aladdin = new Dreamer('Aladdin');
aladdin instanceof P //true
aladdin instanceof ImaginaryT //false
aladdin.travel();
aladdin.wakeUp();
aladdin.sayHello();
如果怕忘记new操作符
var Person = my.Class({
//you can now call the constructor with or without new
constructor: function(name, city) {
if (!(this instanceof Person))
return new Person(name, city);
this.name =
this.city =
下面看一下my.class的源代码解析:
my.Class实现思路基本是这样的,如果只有一个参数,那么声明的是一个基础类,这个参数是用来声明新类的方法和属以及构造函数。它不是继承而来,但它可以被继承。
继承的思路,就是如果有两个参数,第一个参数做为父类被继承,第二参数用来声明新类的方法和属性以及构造函数,它同样可以被继承。
如果有三个以上参数那么,除出第一个参数做为继承的父类,最后一个参数用声明新类的方法和属性以及构造函数。中间的参数是用类来扩展新类的方法。当然也可以通过my.extendClass扩展新方法。
同时,类库为commonJS和浏览环境都提供了支持!
/*globals define:true, window:true, module:true*/
(function () {
// Namespace object
var my = {};
// 保证AMD分模块可用
if (typeof define !== 'undefined')
define([], function () {
else if (typeof window !== 'undefined')
// 保证客户端可用
window.my =
// 保证后台可用
module.exports =
//============================================================================
// @method my.Class
// @params body:Object
// @params SuperClass:function, ImplementClasses:function..., body:Object
// @return function
my.Class = function () {
var len = arguments.
var body = arguments[len - 1];
// 最后一个参数是指定本身的方法
var SuperClass = len & 1 ? arguments[0] : null;
// 第一个参数是指继承的方法,实例和静态部分均继承
var hasImplementClasses = len & 2;
// 如果有第三个参数,那么第二个就是implementClass,这里其实只继承实例对象
var Class, SuperClassE
// 保证构造方法
if (body.constructor === Object) {
Class = function() {};
Class = body.
// 保证后面不覆盖constructor
delete body.
// 处理superClass部分
if (SuperClass) {
// 中间件实现实例属性的继承
SuperClassEmpty = function() {};
SuperClassEmpty.prototype = SuperClass.
Class.prototype = new SuperClassEmpty();
// 原型继承,解除引用
Class.prototype.constructor = C
// 保证constructor
Class.Super = SuperC
// 父对象访问接口
// 静态方法继承,重载superClass方法
extend(Class, SuperClass, false);
// 处理ImplementClass部分,其实只继承实例属性部分,除SuperClass #arguments[0]# 和 body #arguments[length-1]#
if (hasImplementClasses)
for (var i = 1; i & len - 1; i++)
// implement是继承的实例属性部分, 重载父对象implementClass方法
extend(Class.prototype, arguments[i].prototype, false);
// 处理本身声明body部分,静态要STATIC指定,实例部分要删除STATIC部分
extendClass(Class, body);
//============================================================================
// @method my.extendClass
// @params Class:function, extension:Object, ?override:boolean=true
var extendClass = my.extendClass = function (Class, extension, override) {
// 静态部分继承静态部分
if (extension.STATIC) {
extend(Class, extension.STATIC, override);
// 保证实例部分不继承静态方法
delete extension.STATIC;
// 实例属性继继承实例部
extend(Class.prototype, extension, override);
//============================================================================
var extend = function (obj, extension, override) {
// 其实这里的flase是表明,覆盖父对象的方法
if (override === false) {
for (prop in extension)
if (!(prop in obj))
obj[prop] = extension[prop];
// 这里其实不覆盖父对象的方法,包括toString
for (prop in extension)
obj[prop] = extension[prop];
if (extension.toString !== Object.prototype.toString)
obj.toString = extension.toS
&二、KLASS
&项目地址:/ded/klass
先看使用方法:
a、新建一个类
// 声明一个类
var Person = klass(function (name) {
this.name = name
.statics({//静态方法
head: ':)',
feet: '_|_'
.methods({//实例方法
walk: function () {}
b、继承一个类
// SuperHuman 继承 Person
var SuperHuman = Person.extend(function (name) {
// 自动调用父类的构造方法
.methods({
walk: function() {
// 显式声明调用父类的walk方法
this.supr()
this.fly()
fly: function() {}
new SuperHuman('Zelda').walk()
c、字面量方式声明一个类
var Foo = klass({
initialize: function() {
this.foo = 1
getFoo: function () {
return this.foo
setFoo: function (x) {
this.foo = x
return this.getFoo()
d、实现一个类的方法
因为有时候你可能希望覆写或者混合一个实例方法,可以这样:
// 可以传递一个字面量去继承
var Alien = SuperHuman.extend({
beam: function() {
this.supr()
// beam into space
var Spazoid = new Alien('Zoopo')
if (beamIsDown) {
// 覆写beam方法
Spazoid.implement({
beam: function() {
this.supr()
// fallback to jets
this.jets()
下面看一下klass源代码解析:
klass的基本设计思路很明确,极力的模仿其它语言的继承方式。比如:子类构造方法调用父类的构造方法,还可以显式的声明调用父类的方法。
这种判断都是基于正则匹配:fnTest = /xyz/.test(function () {}) ? /\bsupr\b/ : /.*/;关键字"super"
如果显示的声明了要调用父类的方法,那么声明方法的时候,就包装成一个内部调用父类方法且返回相同值的函数,给当前类的方法。
另一方面,构造方法,也是比较灵活的。如果显示的声明了initialize,那么这就是构造方法。否则如果参数是个function那么它就做为构造方法,否则就用父类的构造方法。
通过statics方式添加静态方法,通过实例的implements和静态方法methods添加实例方法。
通过父类的extend实现继承。
同时,类库为commonJS和浏览环境都提供了支持!
* Klass.js - copyright @dedfat
* version 1.0
* /ded/klass
* Follow our software /dedfat :)
* MIT License
!function (context, f) {
// fnTest用来验证是否可能通过正则找出调用super父类方法的方法
var fnTest = /xyz/.test(function () {}) ? /\bsupr\b/ : /.*/,
noop = function (){},
proto = 'prototype',
isFn = function (o) {
return typeof o ===
function klass(o) {
return extend.call(typeof o == f ? o : noop, o, 1);
// 包装成一个借用super同名方法的函数
function wrap(k, fn, supr) {
return function () {
// 缓存原this.super
var tmp = this.
// 暂把this.super改造成借用super的同名方法above
// 供o里显式的声明(fnTest.text(fn)==true)要借用super的同名方法使用
this.supr = supr[proto][k];
// 借用执行并保存返回值
var ret = fn.apply(this, arguments);
// 恢复原this.super
this.supr =
// 返回返回值,保证wrap后的返回值跟原来一致
// 如果o和super有同名方法,且o显式声明借用super的同名方法,就wrap成一个待执行函数供使用
// 如果没有显式的声明借用super的同名方法,或者是o独有的方法,或者不是方法就直接用
function process(what, o, supr) {
for (var k in o) {
// 如果是非继承方法,按方法注释规则执行,最终都放进what
if (o.hasOwnProperty(k)) {
what[k] = typeof o[k] == f
&& typeof supr[proto][k] == f
&& fnTest.test(o[k])
? wrap(k, o[k], supr) : o[k];
// 继承方法的实现,fromSub是用来控制是否继承而来,上面的klass里面fromSub是1,表明非继承而来,构造函数不借用super执行
function extend(o, fromSub) {
// noop做为媒介类实现原型继承的解除引用
noop[proto] = this[proto];
var supr = this,
prototype = new noop(), // 创建实例对象供原型继承使用,解除引用
isFunction = typeof o == f,
_constructor = isFunction ? o : this,// 如果o是一个构造方法就用,否则由this来决定构造函数
_methods = isFunction ? {} : o,
// 如果o是一个{...}应该用methods放到fn原型里,如果里面有initialize就是构造函数,如果o是函数就由上面_constructor决定o是构造函数
fn = function () { // 因为kclass借助了kclass,所以最终实际上返回的就是fn,fn其实就新类的构造函数
//1 如果o是{...}就会被methods直接过滤并添加到fn的原型里,如果o里面有initialize,那么fn的原型里就有initialize,那么它就是构造方法
//2 如果o是function,methods什么也添加不到fn的原型里,但是_constructor会接受o当构造函数
//3 如果o是{....},同时里面也没有initialize,那么就是this当构造函数,如果在klass里由call决定,显然构造函数是noop,如果在非基础类里,构造函数就是父类的构造函数
由于o不是函数不会自动调用父类的构造函数,只是把父类的构造函数当做当前类的构造函数----这都是由于this的指向决定的
console.log(this);
if (this.initialize) {
this.initialize.apply(this, arguments);
// 调用父类构造方法
// 如上面3,o不是函数,不会调用父类的构造方法
// 基础类无父类,不会调用父类构造方法
fromSub || isFn(o) && supr.apply(this, arguments);
// 调用本类构造方法
// 参考上面2,3要么是noop要么是o
console.log(_constructor==noop);
_constructor.apply(this, arguments);
// 构造原型方法的接口
fn.methods = function (o) {
process(prototype, o, supr);
fn[proto] =
return this;
// 执行实现新类原型,保证新类的constructor
fn.methods.call(fn, _methods).prototype.constructor =
// 保证新类可以被继承
fn.extend = arguments.
// 添加实例方法或者静态方法,statics:静态方法,implement实例方法
fn[proto].implement = fn.statics = function (o, optFn) {
// 保证o是一个object对象,如果o是一个字符串,那么就是添一个方法的情况,如果o是一个object对象说明是批量添加的
// 因为要从o里面拷贝
o = typeof o == 'string' ? (function () {
var obj = {};
obj[o] = optFn;
// 添加实例方法或者静态方法,statics:静态方法,implement实例方法
process(this, o, supr);
return this;
// 后台用,nodejs
if (typeof module !== 'undefined' && module.exports) {
module.exports =
var old = context.
klass.noConflict = function () {
context.klass =
return this;
// 前台浏览器用
//window.kclass =
context.klass =
}(this, 'function');
&三、还有一种简单实现
实现思路很简单,就是利用ECMAScript 5 原型式继承Object.create方法,封装成一个方法,如果不支持ECMAScript5的环境,就平移退化到
function F() {};
F.prototype = superCtor.
ctor.prototype = new F();
ctor.prototype.constructor =
同样的,除最后一个参数是当前类的方法声明,其它参数均做为继承父类,需要循环继承,但当这里处理的相对比较简单,没涉及到覆盖。你可以自己动手添加。
var Class = (function() {
* Inherits function.(node.js)
* @param ctor subclass's constructor.
* @param superctor superclass's constructor.
var inherits = function(ctor, superCtor) {
// 显式的指定父类
ctor.super_ = superC
// ECMAScript 5
原型式继承并解除引用
if (Object.create) {
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
// 无Object.create方法的平稳退化
function F() {};
F.prototype = superCtor.
ctor.prototype = new F();
ctor.prototype.constructor =
* Class function.
return function() {
// 最后一个参数是新类方法、属性和构造函数声明
var subClazz = arguments[arguments.length - 1] || function() {};
// initialize是构造函数,否构造函数就是一个空函数
var fn = subClazz.initialize == null ? function() {} : subClazz.
// 继承除最一个参数以的类,多继承,也可以用作扩展方法
for (var index = 0; index & arguments.length - 1; index++) {
inherits(fn, arguments[index]);
// 实现新类的方法
for (var prop in subClazz) {
if (prop == "initialize") {
fn.prototype[prop] = subClazz[prop];
看下面实例:
* The definition of Cat Class.
var Cat = Class({
* Constructor.
* @param name Cat's name
initialize: function(name) {
this.name =
* Eat function.
eat: function() {
alert(this.name + " is eating fish.");
* The definition of Black Cat Class.
var BlackCat = Class(Cat, {
* Constructor.
* @param name Cat's name.
* @param age Cat's age.
initialize: function(name, age) {
// call the constructor of super class.
BlackCat.super_.call(this, name);
this.age =
* Eat function.
eat: function() {
alert(this.name + "(" + this.age + ") is eating dog.");
* The definition of Black Fat Cat Class.
var BlackFatCat = Class(BlackCat, {
* Constructor.
* @param name Cat's name.
* @param age Cat's age.
* @param weight Cat's weight.
initialize: function(name, age, weight) {
// call the constructor of super class.
BlackFatCat.super_.call(this, name, age);
this.weight =
* Eat function.
eat: function() {
alert(this.name + "(" + this.age + ") is eating dog. My weight: " + this.weight);
* The definition of Dog Class.
var Dog = Class({});
var cat = new BlackFatCat("John", 24, "100kg");
cat.eat();
alert(cat instanceof Cat);
alert(cat instanceof BlackCat);
alert(cat instanceof BlackFatCat);
alert(cat.constructor === BlackFatCat);
alert(cat instanceof Dog);
&四、mootools类库的Class
看具体用法:
a、新建一个类
var Cat = new Class({
initialize: function(name){
this.name =
var myCat = new Cat('Micia');
alert(myCat.name); // alerts 'Micia'
var Cow = new Class({
initialize: function(){
alert('moooo');
b、继承的实现
var Animal = new Class({
initialize: function(age){
this.age =
var Cat = new Class({
Extends: Animal,
initialize: function(name, age){
this.parent(age); // calls initalize method of Animal class
this.name =
var myCat = new Cat('Micia', 20);
alert(myCat.name); // alerts 'Micia'.
alert(myCat.age); // alerts 20.
c、扩充类的实现
var Animal = new Class({
initialize: function(age){
this.age =
var Cat = new Class({
Implements: Animal,
setName: function(name){
this.name = name
var myAnimal = new Cat(20);
myAnimal.setName('Micia');
alert(myAnimal.name); // alerts 'Micia'.
五、悟透javascript:语法甘露
先看用法实例
// 创建类Person
var Person = Class(object, {
Create : function(name, age) {
this.name =
this.age =
SayHello : function() {
alert("Hello, I'm " + this.name + ", " + this.age + " years old.");
var BillGates = New(Person, ["Bill Gates", 53]);
BillGates.SayHello();
// Employee继承Person
var Employee = Class(Person, {
Create : function(name, age, salary) {
Person.Create.call(this, name, age);
//调用基类的构造函数
this.salary =
ShowMeTheMoney : function() {
alert(this.name + " $" + this.salary);
var SteveJobs = New(Employee, ["Steve Jobs", 53, 1234]);
SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();
下面是源码分析:显然,多了一个New方法,创建类和新建类的实例都被巧妙的封装了。形成了一个有意义的整体!还有一点不同的地方,所有的类都基于字面量,而不是基于函数。代码很简短,但其中原理却很丰富也很巧妙,可以细细品味一番!
//创建类的函数,用于声明类及继承关系
function Class(aBaseClass, aClassDefine) {
//创建类的临时函数壳
function class_() {
this.Type = aBaseC
//我们给每一个类约定一个Type属性,引用其继承的类
for (var member in aClassDefine)
this[member] = aClassDefine[member];
//复制类的全部定义到当前创建的类
class_.prototype = aBaseC
return new class_();
//创建对象的函数,用于任意类的对象创建
function New(aClass, aParams) {
//创建对象的临时函数壳
function new_() {
this.Type = aC
//我们也给每一个对象约定一个Type属性,据此可以访问到对象所属的类
if (aClass.Create)
aClass.Create.apply(this, aParams);
//我们约定所有类的构造函数都叫Create,这和DELPHI比较相似
new_.prototype = aC
return new new_();
由于写的比较笼统,可能有很多地方没有解析到,也可能有不准确的地方,还望指正。
&看完上面几种解析,相信息自己也可以写出一个自己的封装类库出来,至于,怎么实现看个人喜好了。但基本的思都是一样的基于原型的继承方式和循环拷贝新方法。
阅读(...) 评论()js封装的方法_百度知道
js封装的方法
1、JS封装就是尽量把使用的方式简单化,内部逻辑和使用解耦。通俗的说就是使用的时候只需要知道参数和返回值,其他条件尽量不要使用人员进行设置。2、JS封装的方法有函数方式、对象的方式、闭包的方式。举例1)函数方式function&kk(a,b){&&&内部对a,b怎么处理就不需要关心了}2)对象方式function&kk(a,b){&&&this.x&=&a;&&&this.y&=&b;}var&k&=&new&kk(1,2);//通过面向对象的方式alert(k.x);3)闭包方式function&kk(a,b){&&&var&k&=&1;&&&return&function&tt(){&&&&&&k++;&&&}}var&u&=&kk(1,2);u();//闭包实现累加u();//闭包实现累加
其他类似问题
5人觉得有用
为您推荐:
var&nbsp.&&&function(value){&&};&new&}&&);&&&&&nbsp!&function&&alert(this._age&&E&&&&&};=&&&return&&&&&&&&&=&&&&&nbsp._name+&&&&=&=&&nbsp//简单理解如下;&=&&{&&&&&&&nbsp,age等字段;&&&&&&&&p1;&&&Person(&&&&&&function(){&this,&&nbsp,属性;&&};&&12);=&&&&&&function(){&&&//使用这个类.getAge&nbsp._name&&&&&&&&&nbsp://封装;&&Person(&&&;&&&&&&this,&nbsp.getName&&&&&&&&&&&&&&&&&&&age){&&=&&&&&&nbsp.setAge&&&&&&&nbsp:将人封装成一个类;&&nbsp,方法等封装成类//例如;&&&&p1&nbsp.age&nbsp.eat=function()&&&&&&nbsp:将字段;&&&&&&&&&&&nbsp.eat(),有&&&&&&&&&&&&&&&nbsp.};return&&nbsp,有eat方法&&&&&&&&&张三&quot
可以简单、详细点吗
这已经说的很简单。
其他1条回答
this.getName = function(){
return this/封装,有name.), age){
this:将人封装成一个类:var p1 = new Person(&quot.setAge = function(value){ /
this,有eat方法 function Person(name._age =使用这个类:/p1; }
this,属性;&#47,方法等封装成类&#47,age等字段!& E例如, 12);//
this.getAge = function(){
this._name+&quot:将字段;.eat()._name = name.eat=function()
alert(简单理解如下
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁今天看啥 热点:
Javascript中的包装类型介绍,javascript包装类型  最近不看犀牛书了,那本翻译的特烂而且好拗口,尤其是原型那块说的乱七八糟,后来经同事介绍,买了本js高级程序设计,然后就继续苦逼的看,不吐槽了,继续说说js中有新鲜感的包装类型。
&一:String
  说到String类型,蛮有意思,平时我们都是这样定义一个string类型,如下图:
但是在js中有一点非常特别,那就是string类型是属于基本类型,不属于引用类型,那就说明string的值是保存在“栈”上面的,而很多语言不是这样,比如C#,我觉得js不作为引用类型也是情有可原,毕竟它玩不了多线程,而C#中一个线程栈空间只分配1M,如果string在C#中是值类型的话,那就有爆栈的可能,而js却没有栈空间限制,所以也就不存在爆栈的情况了。
那么下一个问题来了,我们经常会对string进行一系列的操作,比如substring。如下图:
那刚才也说了,string的值是直接保存在栈上面的,那它怎么会有substring呢?按照官网的解释是这样的:这时候会使用String类型把s包装成引用类型。然后使用String类型的内部实现,正好String内部定义了substring方法,所以其实上面的代码在js的内部应该是这样实现的。
var s=new String("hello")
var r=s.substring(3)
可以看到,其实包装类型只是在执行代码的一瞬间,将s包装成了String引用类型,然后再调用String引用类型下面的substring方法,继而重新将“hello”值赋给s,最后的效果就是s="hello", r="lo",如果你仔细观察,你会发现,如果我给s动态的附一个属性,比如color,那么你再次读取color的话,是不会读取color值的,比如下图:
如果你懂了上面我说的原理,那么你对console.log(s.color)等于undefined 就不足以为奇了,我们可以看到,当我使用s.color="red"的时候,js引擎发现有调用属性的写法,会立即在后台动态让其包装成String类型,然后就给String下面新增了一个属性color=red,然后内部立刻会重新设置s的值为“hello”(s="hello"),接下来当你console.log来输出s.color时,js引擎判断又有调用属性的写法,再次new String("hello")了下,自然在这个新的String类型下面是没有color属性的,所以返回undefined了。
  刚才我也说了,这种包装操作是js在后台动态追加和删除的,将基本类型转化为了引用类型,那么两者有多大的区别呢?
&1&:这个不用说,一个栈,一个堆,如果你对C#比较了解,可以认为是一个box和unbox的操作。
&2&: 我们知道所有的引用类型都是继承自object,注意是引用类型,不要被面向对象搞混了,比如在C#中,所有的类型都是object子类,在js
   里面却不是这样,我们可以用instanceof看一下。
二:Boolean
& & 如果你懂得了String这个包装类,那么其实Boolean包装类跟它是一个原理,只不过在Boolean类型的使用中,是有一个注意事项的,我们知道一个引用类型,除非它是null或者undefined,否则它永远都是true,而这个Boolean类型正是做了这个box操作,如下图:
我们看到这个时候b已经不是单纯的基本类型了,而是引用类型,这时候就再也“与或”不出我想要的结果了。还有一个Number包装类,这个也没什么注意事项的,就不说了。
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&&&
Javascript最近更新

我要回帖

更多关于 js基本包装类型 的文章

 

随机推荐