zoukankan      html  css  js  c++  java
  • js数据类型、内置对象、类型判断、隐原型__proto__、原型对象prototype

    6种基本数据类型、2种引用类型:
    Number,String,B
    oolean,Null,Undefined,Symbol;Array、Object
    用typeof可以检测出变量的基本数据类型,但是有个特例,就是null的typeof返回的是object,这个是javascript的历史Bug;ES6新增数据类型Symbol: 表示独一无二的值;
    栈:原始数据类型(Undefined,Null,Boolean,Number、String) 
    堆:引用数据类型(对象、数组和函数)
    内置对象:
    • Object
    • Number
    • String
    • Boolean
    • Array
    • Function
    • Date
    • RegExp
    • Error
    • EvalError:代表了一个关于 eval 函数的错误.
    • RangeError:值超出范围
    • ReferenceError:引用了一个不存在的变量。
    • SyntaxError:当JavaScript引擎在解析代码时遇到不符合语言语法的令牌或令牌顺序时,会抛出SyntaxError。
    • TypeError:表示值的类型非预期类型
    • URIError:全局URI句柄函数使用错误。
    var a = 'guojing'
    console.log(typeof a)
    输出:string
    
    var b = 311
    console.log(typeof b)
    输出:number
    
    var c = true
    console.log(typeof c)
    输出:boolean
    
    var d = []
    console.log(typeof d)
    输出:object
    
    var e = {}
    console.log(typeof e)
    输出:object
    
    var f = null 
    console.log(typeof f)
    输出:object
    
    console.log(typeof g)
    输出:undefined

    var h = function(){}
    console.log(typeof h)
    输出:function

    1.在JS里,万物皆对象。方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对象共有的特点。即:对象具有属性proto,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。

    2.方法(Function)方法这个特殊的对象,除了和其他对象一样有上述proto属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

    L instanceof R 
    //instanceof运算时,通过判断L的原型链上是否存在R.prototype
    L.__proto__.__proto__ ..... === R.prototype ?
    //如果存在返回true 否则返回false
    constructor 就是返回对象相对应的构造函数
    console.log([].constructor == Array);  //true
    console.log({}.constructor == Object);  //true
    console.log("string".constructor == String); //true
    console.log((123).constructor == Number);  //true
    console.log(true.constructor == Boolean);  //true
    注意:
    使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,
    框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,
    这时判断该变量,Array == object.constructor;会返回false;
    原因:
    1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
    2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array。
    使用
        Object.prototype.toString.call(arr) === '[object Array]'
    判断 arr 是否是对象或者数组
    
    function isArray(o) {
      return Object.prototype.toString.call(o);
    }
    var arr=[2,5,6,8];
    var obj={name:'zhangsan',age:25};
    var fn = function () {}
    console.log(isArray(arr)); //[object Array]
    console.log(isArray(obj)); //[object Object]
    console.log(isArray(fn));  //[object function]
    1.一个对象的 __proto__隐式原型 指向构造该对象的构造函数的 prototype原型对象;

    2.实例能够访问在构造函数 原型对象prototype 中定义的属性和方法;
    3.函数是个特殊的对象,除了和其他对象一样有 隐式原型proto之外,还有自己特有的 原型对象prototype;
    4.原型对象prototype 的用途就是包含所有实例共享的属性和方法。

    5.原型对象
    prototype 也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。
    6.在js里,万物皆对象;
    var A = function(){}
    var a = new A()
    console.log(a.__proto__);
    console.log(A.prototype);
    输出:{constructor: ƒ}constructor: ƒ ()__proto__: Object
    console.log(a.__proto__.__proto__);
    console.log(A.prototype.__proto__); console.log(Object.prototype); 输出:{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}constructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()arguments: (...)caller: (...)length: 1name: "set __proto__"__proto__: ƒ ()[[Scopes]]: Scopes[0]
    console.log(a.__proto__.__proto__.__proto__);
    console.log(A.prototype.__proto__.__proto__); console.log(Object.prototype.__proto__); 输出:null

    通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ... 语句上, 它还会影响到所有继承来自该 [[Prototype]] 的对象。

    如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]].。相反, 创建一个新的且可以继承 [[Prototype]] 的对象,推荐使用 Object.create()

    Object.prototype.__proto__ 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能,以确保Web浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf()

    Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
    
    const person = {
        isHuman: false,
        printIntroduction: function () {
            console.log(`My name is ${this.name}. Am I human?${this.isHuman}`);
        }
    };
    
    const me = Object.create(person);
    
    me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
    me.isHuman = true; // 继承的属性可以被覆盖重写

    me.printIntroduction();  //expected output: "My name is Matthew. Am I human? true"
    Object.getPrototypeOf() 方法返回指定对象的原型
    const prototype1
    = {}; const object1 = Object.create(prototype1); console.log(Object.getPrototypeOf(object1) === prototype1);
    输出:true
    console.log(obj1.__proto__ === prototype1);
    输出:true
    再次理解三种实例化对象的方式:
    var
    a={} console.log(a.__proto__) 输出:{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}constructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()
    var B = function(){} var b = new B() console.log(b.__proto__) 输出:{constructor: ƒ}
    var c = Object.create(a) console.log(c.__proto__) 输出:{}
    var d = Object.create(b) console.log(d.__proto__) 输出:B {}
    工欲善其事 必先利其器
  • 相关阅读:
    elemntui-tab添加图标
    动态添加input,然后获取所有的input框中的值
    jmeter_使用接口传递数据
    python_异常
    python_内置函数和open
    jmeter_安装
    jmeter_使用_设置代理录制脚本
    python_函数
    python_while
    python_if、for
  • 原文地址:https://www.cnblogs.com/fengyouqi/p/9567264.html
Copyright © 2011-2022 走看看