美文网首页工作生活
JS数据类型及操作原理

JS数据类型及操作原理

作者: 没了提心吊胆的稗子 | 来源:发表于2019-07-03 22:10 被阅读0次

数据类型

  • 基本数据类型

    • number
    • string
    • boolean
    • null
    • undefined
    • symbol
  • 引用数据类型

    • 对象

      • {} 普通对象
      • []数组
      • /^$/ 正则
      • Math
    • 函数

      • function普通函数

JS 代码运行在浏览器中,是因为浏览器提供了一个供JS代码执行的环境 -> 全局作用域(window/global)

var a = 12, 
var b = a;
b = 13;
cobsole.log(a); // 12

var obj = {name: "lulu"};
var p = obj;
obj.name = "123";
console.log(obj.name); // 123

var m = {name:"javascript"};
var n = m;
n = {name:"前端开发"}; // n在这一步又指向别的空间,m和n就没关系了
console.log(m.name); // javascript

function fn(){
  var ary = Array.prototype.slice.call(arguments) // 把类数组转化成数组
  return eval(ary.join('+'));
}

值类型

按值操作 如var a = 12; 直接把12这个值赋给变量a(让两者建立了链接关系)

对象数据类型

对象类型:
1)浏览器为其开辟一个新的内存空间(不像值类型只有一个值,可以有很多的值),浏览器给空间分配一个16进制的地址,
2)按照一定顺序,分别把对象键值对存储到内存空间中
3)把这个地址赋值给引用类型变量,是两者关联,引用类型就可以通过该地址找到内存空间,对空间里面存储的值进行操作

函数的操作

创建函数(也是对象)

  1. 先开一个新的内存空间,为其分配一个16进制的地址(跟对象中的第一步别无二致)
  2. 把函数体中编写的js代码当作字符串存储到开辟的空间中(函数只创建不执行没啥意义)
  3. 把分配的地址赋值给声明的函数名(function fn和var fn操作原理相同,都是在当前作用域中声明了一个名字,重复)
    跟对象的区别:对象的内存中存的是有意义的字符串,而函数的内存中存的是无意义的字符串

执行函数
执行函数其中的代码

  1. 函数执行的时候浏览器会形成一个新的私有作用域(只能执行函数体中的代码)供函数体中的代码执行
  2. 执行代码之前,先把创建函数时存储的字符串变为真正的js表达式,按照从上到下的顺序在私有作用域中执行

一个函数可以被执行很多次,每次执行相互之间互不干扰
形成的二私有作用域把函数体中的私有变量都保护起来了,在私有作用域中操作私有变量和外界没有关系,外界也无法直接操作私有变量,函数执行的这种保护机制叫做闭包

JS中的堆栈内存

栈内存
即作用域(全局作用域/私有作用域)
[作用]

  • 为js代码提供执行的环境
  • 基本数据类型是直接存放在栈内存中的

堆内存
存储引用数据类型值的,相当于一个存储的仓库
对象存储的是键值对
函数存储的是代码字符串

项目中内存越少越好,我们需要把一些没用的内存处理到
[堆内存]
var obj = {}; 当前对象对应的堆内存被变量obj占用,无法销毁
obj = null; 空对象指针,不指向任何堆内存,谷歌浏览器会在空闲时间把没有被占用的堆内存自动释放(销毁/回收)
[栈内存]
一般情况下函数执行形成栈内存,若函数执行完成,浏览器会把形成的栈内存自动释放;有时候执行完成栈内存不能被释放
全局作用域在加载页面时执行,关闭页面时销毁

变量提升

当前作用域中,js代码自上而下执行,浏览器首先会把var/function关键字进行提前的声明或者定义
声明(declare): var num; 告诉当前作用域有这个名字了
定义(defined): num = 21; 把声明的名字赋一个值
var关键字的只是声明,function声明加定义一起完成

console.log(num);
console.log(fn);
var num = 13;
function fn(){
  console.log(a);
  var a = 10;
  console.log(a);
}
fn();
console.log(num);

变量声明时带var和不带的区别

带var在当前作用域中创建了一个变量。(若当前是全局作用域,也会给全局作用域下添加这个属性)
在全局作用域中不带var,仅是给全局对象设置了一个新的属性名,省略了window.

// 带var
// 变量提升 var a <=> window.a=undefined
console.log(a); // ->undefined
var a = 12;
console.log(a); // ->
console.log(window.a); // ->
// 不带var
console.log(a); // ReferenceError a is not defined 先看他是不是变量,不是,报错
console.log(window.a) //->12
a = 12; // <=> window.a
console.log(window.a) //->12

作用域链

函数执行形成一个私有作用域,保护其中的私有变量,进入私有作用域中首先变量提升(声明过的变量是私有的),然后代码执行
1、执行的时候遇到变量,若为私有,则按照私有处理即可

function fn(){
    console.log(a); // undefined 私有变量
    var a = 12;
    console.log(a); // 12
}
fn();
console.log(a); //全局下没有这个属性  报错

2、如果当前这个变量不是私有的,需要向他的上级作用域进行查找,上级也没有就继续上一级,直到全局作用域,这种查找机制为作用域链
1)如果上级有,在当前进行的操作则都会操作上级的那个变量
2)若上级没有,一直找到window:
变量 = 值 相当于给window设置了一个属性,

console.log(x, y); // undefined, undefined
var x= 10, y = 20;
function fn2() {
    console.log(x, y); //undefined, 20
    var x = y = 100;
    console.log(x, y); // 100(私有) 100(全局)
}
console.log(x, y); // 10 100

只对等号左边的进行变量提升

=: 赋值,左边的是变量,右边都应是值
匿名函数:函数表达式,把函数当作一个值赋给变量或者其他内容

oDiv.onclick = function(){};
// 相当于oDiv.onclick = aaafff111(函数地址)

只对等号左边进行变量提升,右边就是一个值

console.log(fn); // undefined
var fn = function () {

};
console.log(fn); // [Function: fn]

真是项目中应用这个原理,使用函数表达式创建函数
1)只能对等号左边进行提升,变量完成之后,当前函数只是声明了没有定义,执行函数必须放在赋值代码之后
2)可让代码更加严谨

不管条件是否成立,都要进行变量提升

console.log(num); // undefined
console.log(fn); //undefined
if(1 === 1){
    console.log(num); // undefined
    console.log(fn); // 函数体本身
    var num = 12;
    function fn() {
    }
    console.log(num); // 12
    console.log(fn); // 函数体本身
}
console.log(fn); // 函数体本身

不管条件是否成立,判断体中出现的var, function都会进行变量提升,,在最新版本中,function只能提前声明,不能定义(因为不确定判断条件是否成立)
[条件不成立]
进不到判断体中,赋值的代码执行不了,之前声明的变量或者函数依然是undefined
[条件成立]
进入判断体的第一件事是把之前声明但未定义的函数先定义,然后以上而下执行代码
但老版浏览器不管条件是否成立,都会进行函数声明加定义

重名处理

在变量提升阶段,若有重名,不会重新进行声明,但函数的定义会有替换(后替换前)

私有变量

1、私有作用域变量提升阶段,声明过的变量或者函数
2、形参

function add(arg1, arg2){
  var sum = arg1 + arg2; //  sum,arg1, arg2私有变量
  return sum;
}
var sum = add(10, 20); // sum公有

上级作用域

函数的上级作用域跟在哪执行的没关系,在哪定义上级作用域就是谁

var n = 1;
function fn(){
  console.log(n);
}
fn();  // 1
(~function (){
  var n = 2;
  fn(); // 1 fn的宿主环境是当前自执行函数形成的私有作用域
})();

var p = 10;
var obj = {
    p: 20,
    fn: (function () { 
        var p = 30;
        return function () { 
            console.log(p);
        }
    })()
};
// 执行的是return那个函数而不是自执行函数  
// 函数的上级作用域是自执行函数
obj.fn();   // 30
var p = 10;
var obj = {
    p: 20,
    fn: (function () { 
        return function () { 
            console.log(p);
        }
    })()
};
obj.fn(); // 10 自执行函数的上级作用域是全局作用域
var p = 10;
var obj = { 
    p: 20,
    fn: (function () { 
        return function (p) {
            console.log(p);
        }
    })(obj.p)
};
obj.fn(); // 报错 Cannot read property 'p' of undefined 
// 自执行函数执行的时候还obj还没有赋值

相关文章

  • JS数据类型及操作原理

    数据类型 基本数据类型numberstringbooleannullundefinedsymbol引用数据类型对象...

  • JS数据类型判断及原理

    一、typeof 用法:只能判断string, number,boolean,undefined,symbol,f...

  • js数据类型

    JS基本数据类型和引用数据类型(JS 基本数据类型和引用数据类型的区别及浅拷贝和深拷贝) 再讲 js 的基本数据类...

  • JavaScript笔记

    JavaScript笔记js的数据类型(6种)js的==和===字符串的操作数组的操作Math对象的操作JSON操...

  • 详解Js中的数据类型(一)

    整个Js可以简单理解为二个部分,数据部分,操作运算部分。 Js中数据类型分为:原始的数据类型 (由简单数据类型组成...

  • 数据存储之cookie(二)

    数据存储之cookie的属性及js对cookie的读取、写入和删除操作 上一篇介绍为cookie的原理及一些限制之...

  • 前端8大知识体系梳理

    一:JS原理类数据类型,作用域,原型,对象,继承,异步,递归等 二:JS框架类JQuery,React,Vue,A...

  • 函数预解释

    1,js 分为两种数据类型: 基本数据类型:是按照值来操作的 引用数据类型:是按照引用的地址来操作的 引用类型:存...

  • Vue基础第一天

    vue数据类型 1.操作数据 2.JS数据类型 number string boolean null undefi...

  • 前端资料

    ES6新数据类型 Symbol . js变量提升函数提升 js this js 原型及原型链理解 new做了什么 ...

网友评论

    本文标题:JS数据类型及操作原理

    本文链接:https://www.haomeiwen.com/subject/ftgncctx.html