zoukankan      html  css  js  c++  java
  • js总结(一):javascript的类型:基本类型、对象和数组

    javascript 类型分为2种,一个是原始值,另一个是复杂值(对象)。

    一、原始值

     5个原始值是:数字,字符,布尔,null,undefined。

     9个原生的对象构造函数:Number String Boolean Object Function Array Date Regexp Error

    从技术上来讲,从构造函数返回的数字,字符,布尔并不是对象,null和undefined都是非常简单的值,他们不需要构造函数也没有使用new操作符。

    typeof "1"
    "string"
    typeof 1
    "number"
    typeof a
    "undefined"
    typeof true
    "boolean"

     typeof能判断:数字,字符,布尔,object,function,undefined。 注意null和数组,tyopeof都输出object。

    如何存储和复制原始值

    原始值是真实的值复制

    原始值是作为不可细化的值进行存储和操作的

    var a  =1;
    var b =a;
    var a =2;
    console.log (a,b)// 2 1
    var a ={aa:1}
    var b = a;
    a.aa =2;
    console.log(a,b);// Object {aa: 2} Object {aa: 2}
    ar a =1;
    var func = function(num){
         num =2
         console.log(a);
    }
    func(a);\1

    原始值采用的是值比较,对象采用的引用比较

    var a =1;
    var b = new Number(1);
    var c = Number(1);//没有使用new 因此获得的是原始值
    console.log(a==b);\true
    console.log(a===b);\false
    console.log(a===c);\true

    原始值(StringNumberBoolean)在被用作对象时,就像对象。原始值使用toString方式,,一旦调用或者返回该方法时,对象就会转变成原始值。

    如何存储和复制复杂值。复杂值是通过引用进行存储和操作的。复制是复制对象的地址。

    复杂值采用引用比较。

    var a ={aa:1};
    var func = function(num){
         num.aa =2
         console.log(a);\ Object {aa: 2}
    }
    func(a);
    
    var a ={aa:1};
    var func = function(num){
         num =2
         console.log(a);
    }
    func(a);\Object {aa: 1}
    

      

    var a ={aa:1};
    var func = function(num){
         num ={bb:2}
         console.log(num);\Object {bb: 2}
         console.log(a);\Object {aa: 1}
    
    }
    func(a);
    

      

    var a = [1,2,3];
    var b = function(array){
          array.push(4);
          console.log(array);// [1,2,3,4]
    }
    b(a);
    console.log(a)//[1, 2, 3,4]
    var a ={aa:1};
    var b ={aa:1};
    console.log(a==b);\false
    console.log(a===b);\false

    赋值是靠等于号(=),这样相当于是局部变量了,不会对原有的值改变。

    相当于都是引用传递,用等于号相当于给变量赋予一个新的地址,如果继续改变原来地址的值,使用其他方法,2个都会变化。

     更多请参考:http://www.cnblogs.com/52cik/archive/2014/07/01/js-assignment-operators.html

    ==和===什么区别?

    当时同一个类型时,没有区别。如果不是同一个类型,会进行隐式强制类型转换。

    ‘’==‘0’//false
    0==''//true
    0=='0'//true
    

    关于boolean类型,我们记住哪些为假,其他都是true就行了。js的其他任何值都是true,包括new Boolean(false)

    0,-0,null,undefined,false,NaN(非数字),空字符串

    这些值都是假值,但他们是不可以互换的。

    var a = new Boolean(false);
    if(a){console.log(a)}\Boolean {[[PrimitiveValue]]: false}
    

      

    只允许js本身告诉你,这个值是undefined,有东西丢了。如果指定一个对象或者变量等不可以使用,应该使用null,var a =null;

    总结下类型

    原始值(值类型)   1:基本类型是值类型,可以用typeof判断,                 2:占用空间固定保存在栈中 3:保存与复制的是值本身

    复杂值 (引用类型 )1:使用new 方法创建的对象,使用instanceof判断类型2:占用空间不固定,保存在堆中  3:保存与复制的是指向对象的指针。

      js中一共5个原始值,6个typeof能判断的,9个原生的内置的构造函数。

      这5、6、9,构成了js语言的基础。

       5个原始值是:数字,字符,布尔,null,undefined

    二、typeof操作符

       typeof能判断:数字,字符,布尔,object,function,undefined。 注意null和数组,tyopeof都输出object。

          9个原生的对象构造函数:Number String Boolean Object Function Array Date Regexp Error

          type of Number,返回是function, typeof  new Number返回是object。

       原生的构造函数从根本上说是用于创建预制对象的模板,用new 操作符来实例化构造函数。

          js可以用 字面量,来创建大多数原生对象值。而不必使用new String的方式。

       针对字符串、数字和boolean,使用字面量时,只有在该值被视为对象的情况下,才会创建实际的复杂对象。

    原始值,这些值是很简单的,不能由其他的值组成,也叫简单值。

          typeof不能区分出数组和对象,如何判断类型呢?使用Object.prototype.toString.apply()。

          if(value&&typeof value ==='object'&&value.constructor === Array)

         上面的检测如果在不同帧和窗口创建的数组,会给出false,window对象不一样了.

          可靠的方法是if(Object.prototype.toString.apply(value)==="[object  Array]")

        arguments 数组不是一个数组,他只是一个有着length成员属性的对象。

       如下面例子所示 arguments不是普通的array

    var a = function (){
          var b = Object.prototype.toString.apply(arguments);
          console.log(b);
    
    }
    a();//输出[object Arguments] 
    var a = function (){
          var c = [];
          var b = Object.prototype.toString.apply(c);
          console.log(b);
    
    }
    a();//输出[object Array] 

    如何判断类型

    var toString = Object.prototype.toString
    
    var isArray = Array.isArray || function(val) {
        return toString.call(val) === '[object Array]'
    }
    
    var isFunction = function(val) {
      return toString.call(val) === '[object Function]'
    }

    三、instanceof操作符是如何判断是否实例

    prototype里面的属性有constructor.

    默认的prototype属性是一个object对象,可以设置为任何复杂值,忽略设置为原始值.

    虽然他尽是一个对象,但他是特殊性的,圆形链将每个实例都链接至其构造函数的prototype属性。实例与构造函数的 prototype属性之间有一个隐蔽的链接,这就是实例的__proto__。同时实例的constructor属性是通过构造函数prototype的constructor拿到的。

    但是要保留constructor,这样可以让new的实例有constructor的属性,也可以使用instanceof来判断。

    var Foo = function(){}
    
    Foo.prototype={constructor:Foo}
    
    var FooInstance = new Foo;
    
    FooInstance.__proto__=== Foo.prototype;//true
    
    FooInstance.constructor === Foo; //true

    实际上instanceof判断不是依据constructor,而是依据原型链判断,如下面例子

    1 var Foo = function(){};
    2 Foo.prototype={};
    3 var FooInstance = {};
    4 FooInstance.__proto__=Foo.prototype;
    5 console.log(FooInstance instanceof Foo);//true 

    使用原始值,不使用构造函数

    哪些值算是false:false,"",null,0,-0,NaN,undefined,这些算是false其他都是true

    但是请注意下面这个例子

        var a = Boolean(false);
            var b = new Boolean("");
        
            if (a ){console.log(a);}//无法输出
            if (b ){console.log(b);}//Boolean {[[PrimitiveValue]]: false} new 一个相当于一个对象了,就不是false

     三、关于对象和对象字面量

    在javascript中,对象为王;javascript中几乎所有东西都是对象或者用起来像对象。对象只是一组有命名值(也称属性)集合的容器。对象只是属性的容器,每个属性都一个名称和一个值。

    var myObject =new Object();
    myObject['0']= 'f';
    myObject['1']='o';
    console.log(myObject);\ Object {0: "f", 1: "o"}
    

     使用字符串对象,来强调所有东西都是对象  

    var myObject =new String("fo");
    
    console.log(myObject);\String {0: "f", 1: "o", length: 2, [[PrimitiveValue]]: "fo"}
    
    var myObject =new Number("111");
    
    console.log(myObject);\ Number {[[PrimitiveValue]]: 111}
    

    javascript内置了9个原生的对象构造函数,用户也自定义自己的对象构造函数。

    对象是拥有名/值得集合,并拥有一个连接到原型对象的隐藏连接。

    for in循环仅能遍历可枚举的属性,即在遍历对象时可用的属性,例如构造函数属性就不会被显示。

    典型地,预定义的属性不是可列举的,而用户定义的属性总是可列举的。

    Object.prototype.bb=2;
    console.log(Object.prototype["bb"]);\2
    var a ={aa:1}
    for (var i in a){
       console.log(a[i])\1    2
    }
    
      
    
    Object.prototype = {bb:2};//破坏Object会被屏蔽掉
    console.log(Object.prototype.bb)//undefined
    for (var j in Object.prototype){
      console.log(Object.prototype[j])//什么都没有输出
    }
    var a ={aa:1};
      for (var i in a){
      console.log(a[i])//1
    }
    console.log( a.hasOwnProperty("aa"));	//true
    

      

    使用hasOwnProperty验证对象属性是不是来自于原型链,如果都是继承过来的,就没有

    var aaa = {
        a: 123,
        b: 456
    }
    var BBB = function (){};
    BBB.prototype = aaa;
    BBB.prototype.c = 789;
    var bbb = new BBB();
    console.log(bbb);
    for (var i in bbb){
        if(bbb.hasOwnProperty(i) ){
            console.log(i);
            console.log(bbb[i]);    
        }
    }

    BBB {a: 123, b: 456, c: 789}

    里面的hasOwnProperty没有执行,因为都是别人的,不是自己的。

    如果 proName 存在于 object 中且可以使用一个 For…In 循环穷举出来,那么 propertyIsEnumerable 属性返回 true。
    如果 object 不具有所指定的属性或者所指定的属性不是可列举的,那么 propertyIsEnumerable 属性返回 false。
    典型地,预定义的属性不是可列举的,而用户定义的属性总是可列举的。
    propertyIsEnumerable 属性不考虑原型链中的对象。
    function testIsEnumerable(){
      var a = new Array("apple", "banana", "cactus");
      console.log(a.propertyIsEnumerable(1));
    }
    testIsEnumerable()\true
    

      

    var a= function (){var bb = 12; this.aa ="xxx"};
       a.aa="www";
       a.prototype.cc="eee";
       a.prototype.dd=function(){};
    var b = new a;
     for (var i in b){
        console.log(b[i]);
     }
    

      

    关于hasOwnPropery和PropertyIsEnumerable 

    hasOwnProperty().方法用来检测给定的名字是否是对象的只有属性.对于继承属性它将返回false  

    propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到是只有属性且这个属性的可枚举为true是它才返回true.

    参考:http://www.zhihu.com/question/21262706/answer/17691563

     所以如果你只想遍历对象本身的属性,可以:

    for (var key in obj) {
      if (obj.hasOwnProperty(key) {
       ...
      }

    反过来说,没有必要在 for ... in 中去检测 propertyIsEnumerable,因为不可枚举的属性是不会 for...in 出来的。

    propertyIsEnumerable这个方法其实用到的场合非常少,基本上已经被Object.getOwnPropertyDescriptor取代。唯一区别是,后者只能得到own property是否enumerable,而前者包含了整个原型链。

    9个原生的对象构造函数

    当我们new一个对象的时候 js编译器做了一下操作

    1、创建一个新的o 将Person的prototype对象复制给o
    2、调用构造函数,this指向o 如 var returnObject = constructor.apply(o,arguments)
    3、如果returnObject是一个对象 返回returnObject,否则返回object

    参考

    http://www.cnblogs.com/RitaRichard/archive/2011/10/12/2208902.html

    http://yxc-gdut.iteye.com/blog/1840842

    字面量

    var a ={aa:1,bb:2};

    json的表示方法,属性名永远都是字符串类型,可以不用引号。

    点表示方法,用于获取、更新、设置对象的属性都很方便,默认都是字符串,不需要引号。

    括号表示法,属性名称在括号内,如果具体的属性名称需要用引号,如果不指定引号,则是变量。

    var myObject ={"123":"aa","class":"bb"};
    console.log(myObject."123")
    

      

    var myObject ={"123":"aa","class":"bb"};
    console.log(myObject."123")
    Uncaught SyntaxError: Unexpected string
    var myObject ={"123":"aa","class":"bb"};
    console.log(myObject["123"])
    // aa
    var myObject ={123:"aa",class:"bb"};
    console.log(myObject["123"]+","+myObject["class"])
    // aa  bb
    

      

    四、关于数组

    http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/

  • 相关阅读:
    在SAP云平台上部署和运行Docker应用
    SAP ABAP maintanence view的数据校验机制
    SAP CRM user参数CRM_UI_PROFILE是在哪行ABAP代码里读取的
    sublime text的dockerfile语法高亮插件
    SAP Business Application Studio和SAP云平台Destination
    SAP UI5应用访问OData metadata的url和Destination
    SAP CRM note的自动拷贝
    合并二维数组
    redis命令手册
    redis性能测试工具的使用
  • 原文地址:https://www.cnblogs.com/danghuijian/p/4007802.html
Copyright © 2011-2022 走看看