iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > html >JavaScript对象的基础知识点有哪些
  • 935
分享到

JavaScript对象的基础知识点有哪些

2024-04-02 19:04:59 935人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关javascript对象的基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 、对象的基础1.1 类型JavaScript有六种主要语言类

这篇文章给大家分享的是有关javascript对象的基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

1 、对象的基础

1.1 类型

JavaScript有六种主要语言类型:

string , number , boolean ,undefined , null , object

基本类型:string,number,boolean,undefined,null;基本类型本身不是对象。

null

但是 null有时会被当成对象,typeof null 会返回object,实际上null是基本类型。原因是不同对象在底层都是表示为二进制,在JavaScript中二进制前三位都为0会被判断为object类型,null表示全 0,所以typeof时会返回object。

特殊对象子类型

数组

数组也是对象的一种类型,具备一些额外的行为。数组的组织方式比一般的对象要复杂。

函数

函数本质上和普通函数一样,只是可以调用,所以可以操作对象一样操作函数。

1.2 内置对象

String
Number
Date
Boolean
Object
Function
Array

1.3 内容

.a 称之为属性访问,[‘a’]称之为操作符访问。

//对象中的属性名始终是字符串
myobj={}

myobj[myobj]='bar'//赋值

myobj['[object object]'] //'bar'

1.4 可计算属性名

es6 增加可计算属性名,可以在文字形式中使用 [] 包裹一个表达式来当作属性名

var perfix = 'foo'

var myobj={
    [perfix + 'bar'] :'hello'
}

myobj['foobar']//hello

1.5 属性描述符

es5开始,所有属性具备了属性描述符,比如可以直接判断属性是否可读可写等。


 writeble(可读性)
 configurable(可配置性)
 enumerable (可枚举性)

1.6遍历

for in

for in可用来遍历对象的可枚举属性列表(包括[[Prototype]]链),需要手动获取属性值。可以遍历数组及普通的对象

for of

es6新增,可以用来遍历数组的属性值,for of循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有的返回值。
数组有内置的@@iterator,

for of 如何工作?
var arr = [1, 2, 3]
var it = arr[Symbol.iterator]()//迭代器对象
console.log(it.next());//{value: 1, done: false}
console.log(it.next());//{value: 2, done: false}
console.log(it.next());//{value: 3, done: false}
console.log(it.next());//{value: undefined, done: true}

对象如何内置@@iterator,遍历属性的值?

因为对象没有内置一个@@iterator,无法自动完成for…of遍历。但是,可以给你任何想遍历的对象定义@@iterator,举例来说:

  var obj={
      a:1,b:2
  }
  
   Object.defineProperty(obj, Symbol.iterator, {
        enumerable: false,
        writable: false,
        configurable: true,
        value: function () {
            var self = this
            var idx = 0
            var ks = Object.keys(self)
            return {
                next: function () {
                    return {
                        value: self[ks[idx++]],
                        done: (idx > ks.length)
                    }
                }
            }
        }
    })
    
    //手动遍历
    var it = obj[Symbol.iterator]()//迭代器对象
    console.log(it.next());//{value: 1, done: false}
    console.log(it.next());//{value: 2, done: false}
    console.log(it.next());//{value: undefined, done: true}

   //for of 遍历
    for (const v of obj) {
        console.log(v);
    }
    //2
    //3

其他数组遍历函数

 

2、混合类对象

面试题

1、对象的深拷贝和浅拷贝

相关知识

基本类型和引用类型

上面提过,JavaScript的主要的语言类型有六种:string、number、boolean、null、undefined、object;其中前5种属于基本类型,最后的object属于引用类型。

JavaScript的变量的存储方式:栈(stack)和 堆(heap)

栈:自动分配内存空间,系统自动释放,里面存放的是基本类型的值和引用类型的地址

堆:动态分配的内存,大小不定,也不会自动释放。里面存放引用类型的值

基本类型与引用类型最大的区别就是 传值 和 传址 的区别

基本类型采用值传递;引用类型采用的地址(指针)传递,将存放在栈内存中的地址赋值给接收的 变量。

浅拷贝和深拷贝是什么?

浅拷贝:对象的浅拷贝,会对‘主’对象进行拷贝,但不会复制对象里面的对象。‘里面的对象’会在原来的对象和它的副本之间共享。

深拷贝:对对象的深拷贝,不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,所以对一个对象的修改并不会影响另一个对象。

举例来说:

var anotherObject={
    b:"b"
}

var anotherArray=[]

var myObject={
    a:'a',
    b:anotherObject, //引用,不是副本
    c:anotherArray //另外一个引用
}

anotherArray.push(anotherObject,myObject)

如何实现浅拷贝

object

object.assign()、扩展运算符(…)

var obj1 = {x: 1, y: 2}
var obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 1, y: 2}
obj2.x = 2; //修改obj2.x
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 2, y: 2}

var obj1 = {
    x: 1, 
    y: {
        m: 1
    }
};
var obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: {m: 1}}
console.log(obj2) //{x: 1, y: {m: 1}}
obj2.y.m = 2; //修改obj2.y.m
console.log(obj1) //{x: 1, y: {m: 2}}
console.log(obj2) //{x: 2, y: {m: 2}}
Array

slice()、concat、Array.from()、扩展运算符(…)、concat、for循环

var arr1 = [1, 2, [3, 4]], arr2 = arr1.slice();
console.log(arr1); //[1, 2, [3, 4]]
console.log(arr2); //[1, 2, [3, 4]]

arr2[0] = 2 
arr2[2][1] = 5; 
console.log(arr1); //[1, 2, [3, 5]]
console.log(arr2); //[2, 2, [3, 5]]

如何实现深拷贝

JSON.parse(jsON.stringify(obj))

进行JSON.stringify()序列化的过程中,undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。

var obj1 = {
    x: 1, 
    y: {
        m: 1
    },
    a:undefined,
    b:function(a,b){
      return a+b
    },
    c:Symbol("foo")
};
var obj2 = JSON.parse(JSON.stringify(obj1));

console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)}
console.log(obj2) //{x: 1, y: {m: 1}}
obj2.y.m = 2; //修改obj2.y.m
console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)}
console.log(obj2) //{x: 2, y: {m: 2}}
深拷贝函数的简单实现
function deepClone(obj){
  let result = Array.isArray(obj)?[]:{};
  if(obj && typeof obj === "object"){
    for(let key in obj){
      if(obj.hasOwnProperty(key)){
        if(obj[key] && typeof obj[key] === "object"){
          result[key] = deepClone(obj[key]);
        }else{
          result[key] = obj[key];
        }
      }
    }
  }
  return result;
}

var obj1 = {
    x: {
        m: 1
    },
    y: undefined,
    z: function add(z1, z2) {
        return z1 + z2
    },
    a: Symbol("foo"),
    b: [1,2,3,4,5],
    c: null
};
var obj2 = deepClone(obj1);
obj2.x.m = 2;
obj2.b[0] = 2;
console.log(obj1);
console.log(obj2);

//obj1
{
a: Symbol(foo)
b: (5) [1, 2, 3, 4, 5]
c: null
x: {m: 1}
y: undefined
z: ƒ add(z1, z2)
}

//obj2
{
a: Symbol(foo)
b: (5) [2, 2, 3, 4, 5]
c: null
x: {m: 2}
y: undefined
z: ƒ add(z1, z2)
}

上面的深拷贝方法遇到循环引用,会陷入一个循环的递归的过程,从而导致爆栈。因此需要改进。

深拷贝函数的改进(防止循环递归)

解决因循环递归而暴栈的问题,只需要判断一个对象的字段是否引用了这个对象或这个对象的任意父级即可。

function deepClone(obj, parent = null){ // 改进(1)
  let result = Array.isArray(obj)?[]:{};
  let _parent = parent;  // 改进(2)
  while(_parent){ // 改进(3)
    if(_parent.originalParent === obj){
      return _parent.currentParent;
    }
    _parent = _parent.parent;
  }
  if(obj && typeof obj === "object"){
    for(let key in obj){
      if(obj.hasOwnProperty(key)){
        if(obj[key] && typeof obj[key] === "object"){
          result[key] = deepClone(obj[key],{ // 改进(4)
            originalParent: obj,
            currentParent: result,
            parent: parent
          });
        }else{
          result[key] = obj[key];
        }
      }
    }
  }
  return result;
}

// 调试用
var obj1 = {
    x: 1, 
    y: 2
};
obj1.z = obj1;
var obj2 = deepClone(obj1);
console.log(obj1); 
console.log(obj2);
深拷贝函数最终版(支持基本的数据类型、原型链、RegExp、Date类型)
function deepClone(obj, parent = null){ 
  let result; // 最后的返回结果

  let _parent = parent; // 防止循环引用
  while(_parent){
    if(_parent.originalParent === obj){
      return _parent.currentParent;
    }
    _parent = _parent.parent;
  }
  
  if(obj && typeof obj === "object"){ // 返回引用数据类型(null已被判断条件排除))
    if(obj instanceof RegExp){ // RegExp类型
      result = new RegExp(obj.source, obj.flags)
    }else if(obj instanceof Date){ // Date类型
      result = new Date(obj.getTime());
    }else{
      if(obj instanceof Array){ // Array类型
        result = []
      }else{ // Object类型,继承原型链
        let proto = Object.getPrototypeOf(obj);
        result = Object.create(proto);
      }
      for(let key in obj){ // Array类型 与 Object类型 的深拷贝
        if(obj.hasOwnProperty(key)){
          if(obj[key] && typeof obj[key] === "object"){
            result[key] = deepClone(obj[key],{ 
              originalParent: obj,
              currentParent: result,
              parent: parent
            });
          }else{
            result[key] = obj[key];
          }
        }
      }
    }
  }else{ // 返回基本数据类型与Function类型,因为Function不需要深拷贝
    return obj
  }
  return result;
}

// 调试用
function construct(){
    this.a = 1,
    this.b = {
        x:2,
        y:3,
        z:[4,5,[6]]
    },
    this.c = [7,8,[9,10]],
    this.d = new Date(),
    this.e = /abc/ig,
    this.f = function(a,b){
        return a+b
    },
    this.g = null,
    this.h = undefined,
    this.i = "hello",
    this.j = Symbol("foo")
}
construct.prototype.str = "I'm prototype"
var obj1 = new construct()
obj1.k = obj1
obj2 = deepClone(obj1)
obj2.b.x = 999
obj2.c[0] = 666
console.log(obj1)
console.log(obj2)
console.log(obj1.str)
console.log(obj2.str)

注:Function类型的深拷贝:

bind():使用fn.bind()可将函数进行深拷贝,但因为this指针指向问题而不能使用;

eval(fn.toString()):只支持箭头函数,普通函数function fn(){}则不适用;

new Function(arg1,arg2,…,function_body):需将参数与函数体提取出来;

感谢各位的阅读!关于“JavaScript对象的基础知识点有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: JavaScript对象的基础知识点有哪些

本文链接: https://www.lsjlt.com/news/87861.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript对象的基础知识点有哪些
    这篇文章给大家分享的是有关JavaScript对象的基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 、对象的基础1.1 类型JavaScript有六种主要语言类...
    99+
    2022-10-19
  • JavaScript基础知识点有哪些
    这篇文章主要介绍“JavaScript基础知识点有哪些”,在日常操作中,相信很多人在JavaScript基础知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java...
    99+
    2022-10-19
  • javascript中Ajax基础知识点有哪些
    小编给大家分享一下javascript中Ajax基础知识点有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Ajax基础Aja...
    99+
    2022-10-19
  • JavaScript基础入门知识点有哪些
    这篇文章给大家分享的是有关JavaScript基础入门知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。JavaScript简介JavaScript(Java脚本)是一种基于对象(Object)和事件驱动...
    99+
    2023-06-27
  • JavaScript的变量基础知识点有哪些
    这篇文章给大家分享的是有关JavaScript的变量基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。变量1.1 变量的概念:变量是指程序中一个已经命名的储存单位,它...
    99+
    2022-10-19
  • QinQ基础知识点有哪些
    本篇内容主要讲解“QinQ基础知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“QinQ基础知识点有哪些”吧!QinQ 是 802.1Q in 802.1Q 的简称,是基于 IEEE 8...
    99+
    2023-06-03
  • Mysql基础知识点有哪些
    这篇文章主要介绍Mysql基础知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!数据库的特点?数据结构化 ,数据之间具有联系,面向整个系统;数据的共享性高,冗余度低,易扩充;...
    99+
    2022-10-18
  • Redis基础知识点有哪些
    本篇内容介绍了“Redis基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 什么是Red...
    99+
    2022-10-19
  • Node.js基础知识点有哪些
    这篇文章给大家分享的是有关Node.js基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Node.js是什么根据Node.js官方网站的描述,“Node.js是一套...
    99+
    2022-10-19
  • jQuery基础知识点有哪些
    这篇文章将为大家详细讲解有关jQuery基础知识点有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。jQuery语法实例$(this).hide()jQuery 的 h...
    99+
    2022-10-19
  • InnoDB基础知识点有哪些
    这篇文章给大家分享的是有关InnoDB基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、关于count(*)知识点:MyISAM会直接存储总行数,InnoDB则不...
    99+
    2022-10-19
  • Angular8基础知识点有哪些
    这篇文章给大家分享的是有关Angular8基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Angular CLI又称 Angular脚手架,用于快速生成项目或者组件...
    99+
    2022-10-19
  • XHTML基础知识点有哪些
    本篇内容介绍了“XHTML基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 一.HTML实...
    99+
    2022-10-19
  • html基础知识点有哪些
    这篇文章主要介绍了html基础知识点有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。HTML语义化HTML标签的语义化是指:通过使用包含...
    99+
    2022-10-19
  • css3基础知识点有哪些
    这篇文章主要讲解了“css3基础知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“css3基础知识点有哪些”吧! div > p 选择父元素...
    99+
    2022-10-19
  • CSS基础知识点有哪些
    这篇文章主要为大家展示了“CSS基础知识点有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CSS基础知识点有哪些”这篇文章吧。CSS3 选择器选择器可以被分...
    99+
    2022-10-19
  • Hibernate基础知识点有哪些
    这篇文章主要介绍“Hibernate基础知识点有哪些”,在日常操作中,相信很多人在Hibernate基础知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate基础知识点有哪些”的疑惑有所...
    99+
    2023-06-17
  • Java基础知识点有哪些
    这篇文章主要介绍“Java基础知识点有哪些”,在日常操作中,相信很多人在Java基础知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java基础知识点有哪些”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-02
  • VBS基础知识点有哪些
    这篇文章给大家分享的是有关VBS基础知识点有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。VBScript(Microsoft Visual Basic Script Editon).,微软公司可视化BASI...
    99+
    2023-06-08
  • MongoDB基础知识点有哪些
    这篇文章主要介绍MongoDB基础知识点有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!NO.1 Linux下MongoDB的安装   Linux下MongoDB的安装还算简单,总体可以分为如...
    99+
    2023-06-14
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作