js深拷贝deepCopy教程:支持循环引用、类型不丢失、可扩展、可定制

article/2025/1/18 18:06:12

目录

  • 1. 背景
  • 2. 简介
  • 3. 安装方式
    • 3.1. 方式1:通过 npm 安装
    • 3.2. 方式2:直接下载原代码
    • 3.3. 方式3:通过<script>标签引入
  • 4. 教程
    • 4.1. API简介
    • 4.2. 基本使用
    • 4.3. 拷贝函数
    • 4.4. 指定拷贝深度
    • 4.5. 循环引用
    • 4.6. 保持类型信息
    • 4.7. 拷贝不可枚举的属性
    • 4.8. 自定义拷贝规则
      • 4.8.1. typeCopyers
        • 4.8.1.1. Types
        • 4.8.1.2. 拷贝者Copyer
      • 4.8.2. 预设presetTypeCopierMap
      • 4.8.3. 拷贝者的优先级
      • 4.8.4. getCopy
    • 4.9. 创建带预设拷贝规则的拷贝函数

内容

1. 背景

开发中,经常需要对一个对象进行深拷贝操作,目前经常用到的深拷贝的方式有以下几种:

  • 将对象序列化成 JSON 字符串后,再反序化成对象 let copy = JSON.parse(JSON.stringify(value))
  • 第三方库提供的深拷贝工具,如 Lodash 的 _.cloneDeep(value)_.cloneDeepWith(value, customizer)

但这些方法有以下缺点:

  • 不支持对象成员循环引用,比如下面这种:
    循环引用
  • 拷贝后会丢失类型信息,变成了普通的对象
  • 拷贝后会丢失成员引用关系信息
  • 不能根据类型自定义拷贝规则
  • 只能拷贝可枚举的属性
  • 不能拷贝函数
  • 不能指定拷贝深度

为了解决这些问题,deep-copy 就出现了👏

2. 简介

deep-copy 是一个深拷贝工具,可对任意数据进行深度拷贝,包括 函数 function、正则 RegExp、Map、Set、Date、Array、URL 等等;支持含循环引用关系的对象的拷贝,并且不会丢失成员的引用关系信息 和 类型信息,支持扩展,可根据数据类型定制拷贝逻辑,也可指定拷贝深度;所以,通过它可实现对任意类型的数据进行任意想要的拷贝;

具有以下特性:

  • 支持对象成员循环引用
  • 拷贝后不会丢失类型信息 和 成员引用关系信息
  • 可指定拷贝深度
  • 即能拷贝可枚举的成员,也可拷贝不可枚举的成员
  • 可拷贝函数
  • 可根据类型自定义拷贝规则
  • 支持预设拷贝规则
  • 支持创建多个不同预设拷贝规则的拷贝函数

详情请看:

  • 主页:https://github.com/GuoBinyong/deep-copy
  • GitHub仓库
  • 码云仓库

如果您在使用的过程中遇到了问题,或者有好的建议和想法,您都可以通过以下方式联系我,期待与您的交流:

  • 给该仓库提交 issues
  • 给我 Pull requests
  • 邮箱:guobinyong@qq.com
  • QQ:guobinyong@qq.com
  • 微信:keyanzhe

3. 安装方式

目前,安装方式有以下几种:

3.1. 方式1:通过 npm 安装

npm install @gby/deep-copy

3.2. 方式2:直接下载原代码

您可直接从项目的 发行地址 下载 源码 或 构建后包文件;

您可以直接把 源码 或 构建后 的包拷贝到您的项目中去;然后使用如下代码在您的项目中引入 deepCopy

import { deepCopy } from "path/to/package/deep-copy";

或者

import deepCopy from "path/to/package/deep-copy";

3.3. 方式3:通过<script>标签引入

您可直接从项目的 发行地址 中下载以 .iife.js 作为缀的文件,然后使用如下代码引用 和 使用 deep-copy:

  1. 引用 deep-copy

    <script src="path/to/package/deep-copy.iife.js"></script>
    
  2. 使用全局的 deepCopy

    <script>
    // 使用全局的 deepCopyconst copy = deepCopy.deepCopy(value);
    </script>
    

4. 教程

4.1. API简介

deep-copy 导出了两个工具函数

import {deepCopy,createDeepCopy} from "deep-copy"
  • deepCopy<V>(value:V,options?:DeepCopyOptions|null|undefined,typeCopyers?:TypeRevivers<Copier>|null|undefined):V:对 value 进行深拷贝操作,并将深拷贝后的值返回;参数如下:

    • value: any:被拷贝的值;
    • options?:DeepCopyOptions|null|undefined:描述拷贝配置的选项对象;
    • typeCopyers?:TypeRevivers<Copier>|null|undefined:可根据不同类型定制拷贝逻辑的配置对象
  • createDeepCopy(presetTypeCopierMap?:TypeReviverMap<Copier>):DeepCopy:创建并返回带有默认 typeCopyers 的 deepCopy() 函数;参数如下:

    • presetTypeCopierMap?:TypeReviverMap<Copier>:默认的 typeCopyers;

4.2. 基本使用

deep-copy 库中 会导出 deepCopy() 函数,用它可以直接对值进行深拷贝,如下所示:

import {deepCopy} from "../dist/deep-copy.es"let value = {name:"root",sub:{name:"member1",fun:function () {console.log("这是函数")}}
};let copy = deepCopy(value);

其中 copy 和 value 的信息结构是完全一样的,但 copy 和 value 及其成员(除了函数(方法)外)已经是完全两份实例,占据着两份不同的内存空间;

4.3. 拷贝函数

默认情况下,deepCopy() 不会对 函数对象 进行深拷贝,比如上例中的 value.sub.fun,所以,copy 中的函数(方法) 和 value 中的函数 是同一函数,占据同一份内存空间,即 copy.sub.fun === value.sub.fun

如果希望 deepCopy() 对函数也进行深拷贝,可以给 deepCopy() 传递第2个参数并设置选项 copyFuntrue,如下所示:

let copy = deepCopy(value,{copyFun:true
});

些时,copy 中的函数(方法) 和 value 中的函数 具有相同的代码逻辑,但已经是两个不同的函数实例,占据不同的内存空间,即 copy.sub.fun !== value.sub.fun

4.4. 指定拷贝深度

如果你只需要实例进行一定深度的深拷贝,比如:只对实例、实例的成员、实例的成员的成员 进行拷贝操作,再深入的不进行拷贝操作,像这样的需求,可以通过给 deepCopy 传递 maxDepth 选项来实现,如下:

let copy = deepCopy(value,{maxDepth:2
});

maxDepth 是可选的,默认值为:Infinity;表示拷贝的最大深度;当值为 undefinednull 时,会使用默认值,表示无限深度;被拷贝的值(本例中是 value)本身的深度为 0 ,被拷贝值的成员的深度为 1 ,依次类推;

4.5. 循环引用

当对象 与 对象 之间 或 对象 与 成员 之前 存在类似以下引用关系时,就会形成循环引用
循环引用

JSON的深拷贝方案是无法处理循环引用关系 let copy = JSON.parse(JSON.stringify(value)),会造成内存溢出;

deepCopy() 支持拷贝这种带循环引用关系的对象,并且拷贝后的值,仍然会保持这种循环引用关系,如下所示:

let root = {name:"root"
};let member1 = {name:"member1",fun:function () {console.log("这是函数")}
};let member2 = {name:"member2",
};root.sub = member1;
member1.sub = member2;
member2.sub = root;let rootCopy = DC.deepCopy(root);

拷贝前 和 拷贝后的 引用关系保持一样:

root.sub.sub.sub === root;  // true
rootCopy.sub.sub.sub === rootCopy;  // true

4.6. 保持类型信息

有些时候,被拷贝的对象并不是普通的对象,它可能是某个类的实例,比如:

class Person {constructor(){this.name = "";this.email = "";}
}let p = new Person();
p.name = "郭斌勇";
p.email = "guobinyong@qq.com";

p 是 类 Person 的实例,但通过 JSON方案拷贝后

let pCopy = JSON.parse(JSON.stringify(p));pCopy instanceof Person; // false
pCopy instanceof Object; // true

pCopy 却变成了普通对象,即 Object 类型的实例;

然而,deepCopy() 会保持这种类型信息,如下:

let pCopy = deepCopy(p);
pCopy instanceof Person;  // true

拷贝后的 pCopy 仍然是 Person 类型的实例;

注意:
deep-copy 在拷贝实例时,会用实例所属的类创建一个新的实例,创建时并不会给构造函数传递任何参数, 然后将原来实例本身的成员的副本重设 新实例为新实例的成员;这对于那些需要给构造函数传递参数的类 可能会存在问题;如果某类创建实例时依赖构造函数的参数,则您可以针对些类定制拷贝规则;

4.7. 拷贝不可枚举的属性

deepCopy() 默认只拷贝对象自身的可枚举属性,如果您也想拷贝对象自身的不可枚举的属性,则可以给 deepCopy() 传递 allOwnProps 选项,并设置为 true,如下:

let copy = deepCopy(value,{allOwnProps:true
});
  • allOwnProps?:boolean | undefined | null:可选选项;默认值: undefined; 表示是否要拷贝所有自身的属性,包不可枚举的,但不包括原型链上的属性;
    • true:拷贝对象自身(不包括原型上的)的所有属性(包括不可枚举的);
    • false|undefined|null : 只拷贝对象自身中(不包括原型上的)可枚举的属性;

4.8. 自定义拷贝规则

对于下面这个 Person 类,在创建实例时(比如:p)需要传入一个构造参数 sex,这个参数决定了模型的构建过程,如下:

class Person {constructor(sex){this.sex = sex;// 根据 sex  初始化模型switch(sex){case "男":{console.log("初始化男性特性");break;}case "女":{console.log("初始化女性特性");break;}default:{console.log("初始化人妖特性");}}this.name = "";this.email = "";this.idCard = null; //身份证,是一个对象this.mate = null;  //配偶,也是 Person 类的实例}
}let p = new Person("男");
p.name = "郭斌勇";
p.email = "guobinyong@qq.com";
p.idCard = {id:4231232776886677,  //身份address:"中国的一个小农村里"
};//设置配偶
p.mate = new Person("女");
p.mate.name = "简爱";

像这种类型的类,如果使用 deepCopy() 的默认拷贝逻辑的话,新拷贝的 Person 实例可能会执行错误的构建过程,因为 deepCopy() 在创建新实例时,不会传入任何构建参数;像这种类型,我们就需要提供自定义的拷贝规则了;

如果你想自定义某个类型实例的深拷贝规则,有以下几种方案:

  • deepCopy() 函数提供 typeCopyers 参数 或 设置 presetTypeCopierMap 预设;
  • 给实例增加 getCopy 方法;

4.8.1. typeCopyers

可以通过 typeCopyers 参数自定义拷贝规则,如下:

let pCopy = deepCopy(p,null,{// 当需要拷贝 Person 类型的实例时,会回调这个函数,这个函数需要返回 Person 实例的副本;这个函数称为 拷贝者 Copier"Person": function(value,copyMember,options){let copy = new Person(value.sex);  // 创建新的 Person 实例,作为 value 的副本// 给副本 copy 设置基本类型的成员;copy.name = value.name;copy.email = value.email;// 如果引用类型的成员也需要深拷贝,则需要通过 copyMember() 函数拷贝 引用类型的成员copy.idCard = copyMember(value.idCard);/*** copyMember() 函数会返回 拷贝后的值;* 但如果被拷贝的值存在循环引用的话,copyMember() 会返回 undefined;这种情况下,可通过给 copyMember() 传递回调函数(第2个参数),通过回调函数来获取拷贝后的值;* 无论是否存在循环引用,通过回调函数总能拿到拷贝后的值,回调函数是一种保险的方法*/copyMember(value.mate,function(mateCopy){copy.mate = mateCopy;});// 需要将副本返回;return copy;}
});

deepCopy() 函数的 typeCopyers 参数是 TypeRevivers<Copier> 类型的,是用来描述 类型 和 拷贝者 Copier(提供拷贝实例回调函数)的对应关系的,上例中 typeCopyers 使用的是 对象形式,它共以下几种描述方式:

  • {[TypeName:ExactTypeName]:Copyer}:对象形式,属性名字 是 类型的名字,属性值是类型的 拷贝者(Copyer);
  • [Types, Copyer][]:数组形式,数组中的元素是 [Types, Copyer] 类型的元组,元组的第一个元素是 Types,第二个元素是 拷贝者;
  • Map<Types, Copyer>:Map形式,Map中的键是 Types 类型,值是 拷贝者;

4.8.1.1. Types

TypesExactTypeNameExactType 和 其数组结构的联合,定义如下:

type Types = DataType | DataTypeArray;
type DataType = ExactTypeName | ExactType;
type DataTypeArray = DataType[];
  • ExactType:精确类型,可更加细致地描述类型;各种类型的值(左侧) 与 ExactType(右侧) 的映射如下:

    • undefinedundefined
    • null : null
    • string : "string"
    • number : "number"
    • bigint : "bigint"
    • boolean : "boolean"
    • symbol : "symbol"
    • 普通函数 : Function
    • 异步函数 : AsyncFunction
    • 生成器函数 : GeneratorFunction
    • 没有原型的对象(如:通过 Object.create(null) 创建的对象) : "object"
    • 其它任何类型的实例 : 该实例的构造函数
  • ExactTypeName:精确类型的字符串表示;各种类型的值(左侧) 与 ExactTypeName(右侧) 的映射如下:

    • undefined"undefined"
    • null : "null"
    • string : "string"
    • number : "number"
    • bigint : "bigint"
    • boolean : "boolean"
    • symbol : "symbol"
    • 普通函数 : "Function"
    • 异步函数 : "AsyncFunction"
    • 生成器函数 : "GeneratorFunction"
    • 没有原型的对象(如:通过 Object.create(null) 创建的对象) : "object"
    • 其它任何类型的实例 : 该实例的构造函数的名字

所以,Types 可以是具体的类型 ExactType ,比如:Person 类;也可以是 类型的名字字符串 ExactTypeName ,比如:'Person';或者是包含多个类型的数组,比如:[Person,'Map',Set]

4.8.1.2. 拷贝者Copyer

拷贝者 Copyer 是一个类型为 (value:T,copyMember:CopyMember,options:CopierOptions)=>T 函数,严格的定义如下:

type Copier<T = any,Host = any> = (this:T,value:T,copyMember:CopyMember,options:CopierOptions<Host>)=>T

当需要拷贝某个类型的实例时,就会调用这个类型的 拷贝者 Copyer ,然后将拷贝者返回的值作为那个实例的副本;

在调用拷贝者 Copyer 时,会将 Copyer 的 this 设置为被拷贝的值(与 value 参数相同的值),并会给 Copyer 传递以下参数:

  • value:被拷贝的值;
  • copyMember:用于深拷贝 value 的成员的深拷贝函数;类型为 (member:T,completeCB?:CompleteCB<T>|null|undefined,key?:K,host?:H | null | undefined,options?:CopyMemberOptions)=>T|undefined;拷贝后副本会通过 copyMember() 的返回值(当被拷贝的成员不存在循环引用时) 和 completeCB 回调函数 返回;
  • options:包含了其它信息的对象
     {allOwnProps:boolean;key:any;host:Host;type:string;depth:number;copyFun:boolean;
    }
    

拷贝者 Copyer 需要将自定创建的 value 的副本返回;

在创建 value 的副本的过程中,如果需要对 value 的引用类型的成员 进行拷贝,则需要调用 copyMember(value) 函数,这个函数是专门用于 深拷贝 value 的成员的;拷贝后副本会通过 copyMember(value) 的返回值(当被拷贝的成员不存在循环引用时) 和 传给 copyMember(value,completeCB)completeCB 回调函数 传回;例外的情况是:如果 value 的某个成员存在循环引用,则 copyMember(value) 会返回 undefined,这种情况下,只能通过 completeCB 回调函数 传回拷贝后的值;

4.8.2. 预设presetTypeCopierMap

如果经常需要给 deepCopy() 传递包含相同 类型和拷贝者 的 typeCopyers 参数,则可以将那些经常用到的 拷贝者 设置到 deepCopy() 的预设 deepCopy.presetTypeCopierMap 中;

deepCopy 函数对象有个属性 presetTypeCopierMap 是用来设置常用的拷贝者的,它的类型是 Map<Types, Reviver>,所以上面的例子也可以如下设置预设:

// 当需要拷贝 Person 类型的实例时,会回调些函数
deepCopy.presetTypeCopierMap.set(Person,function(value,copyMember,options){let copy = new Person(value.sex);  // 创建新的 Person 实例,作为 value 的副本// 给副本 copy 设置基本类型的成员;copy.name = value.name;copy.email = value.email;// 如果引用类型的成员也需要深拷贝,则需要通过 copyMember() 函数拷贝 引用类型的成员copy.idCard = copyMember(value.idCard);/*** copyMember() 函数会返回 拷贝后的值;* 但如果被拷贝的值存在循环引用的话,copyMember() 会返回 undefined;这种情况下,可通过给 copyMember() 传递回调函数(第2个参数),通过回调函数来获取拷贝后的值;* 无论是否存在循环引用,通过回调函数总能拿到拷贝后的值,回调函数是一种保险的方法*/copyMember(value.mate,function(mateCopy){copy.mate = mateCopy;});// 需要将副本返回;return copy;
})

以后使用 deepCopy() 时,就不需要传递 Person 类型的拷贝者了;

4.8.3. 拷贝者的优先级

当需要拷贝某个类型的实例时,deepCopy() 会通过以下几种方法获取该实例的副本:

  • 首先使用 typeCopyers 参数中的拷贝者;
  • 如果没有找到拷贝者,则再使用预设 presetTypeCopierMap 中的拷贝者;
  • 如果没有找到拷贝者,则会将实例的 getCopy 方法作为拷贝者;
  • 如果实例没有 getCopy 方法,则会使用 typeCopyers 参数中 "default" 对应的 拷贝者;
  • 如果没有找到拷贝者,则会使用预设 presetTypeCopierMap"default" 对应的 拷贝者;
  • 如果没有找到拷贝者,则会使用内置的默认拷贝逻辑;

其中,"default" 对应的拷贝者称为 默认的拷贝者;

4.8.4. getCopy

通过上文的 [拷贝者的优先级][] 可以知道,我们也可以给对象增加 getCopy 方法 来自定义 该对象的拷贝逻辑,如果您想将拷贝者应用到某个类型的所有实例上,则只需要给该类型增加一个实例方法 getCopy 即可;

getCopy 方法的 和 拷贝者 Copier 的类型一样,都是类型为 (value:T,copyMember:CopyMember,options:CopierOptions)=>T 函数;

所以,上例中,也可以如下自定义 实例 p 的拷贝逻辑:

p.getCopy = function(value,copyMember,options){let copy = new Person(value.sex);  // 创建新的 Person 实例,作为 value 的副本// 给副本 copy 设置基本类型的成员;copy.name = value.name;copy.email = value.email;// 如果引用类型的成员也需要深拷贝,则需要通过 copyMember() 函数拷贝 引用类型的成员copy.idCard = copyMember(value.idCard);/*** copyMember() 函数会返回 拷贝后的值;* 但如果被拷贝的值存在循环引用的话,copyMember() 会返回 undefined;这种情况下,可通过给 copyMember() 传递回调函数(第2个参数),通过回调函数来获取拷贝后的值;* 无论是否存在循环引用,通过回调函数总能拿到拷贝后的值,回调函数是一种保险的方法*/copyMember(value.mate,function(mateCopy){copy.mate = mateCopy;});// 需要将副本返回;return copy;
};

或,如下自定义 Person 类型 的拷贝逻辑:

Person.prototype.getCopy = function(value,copyMember,options){let copy = new Person(value.sex);  // 创建新的 Person 实例,作为 value 的副本// 给副本 copy 设置基本类型的成员;copy.name = value.name;copy.email = value.email;// 如果引用类型的成员也需要深拷贝,则需要通过 copyMember() 函数拷贝 引用类型的成员copy.idCard = copyMember(value.idCard);/*** copyMember() 函数会返回 拷贝后的值;* 但如果被拷贝的值存在循环引用的话,copyMember() 会返回 undefined;这种情况下,可通过给 copyMember() 传递回调函数(第2个参数),通过回调函数来获取拷贝后的值;* 无论是否存在循环引用,通过回调函数总能拿到拷贝后的值,回调函数是一种保险的方法*/copyMember(value.mate,function(mateCopy){copy.mate = mateCopy;});// 需要将副本返回;return copy;
};

4.9. 创建带预设拷贝规则的拷贝函数

如果您在使用 deepCopy() 时,经常需要使用不同的预设,那您可能需要使用 createDeepCopy(presetTypeCopierMap) 来创建一个带有预设 presetTypeCopierMap 的另一个新的 deepCopy() 函数;

createDeepCopy(presetTypeCopierMap) 方法会创建一个新的深拷贝函数,这个新的深拷贝函数 和 deepCopy() 具有相同的功能,只是 不同的对象,且预设为传给 createDeepCopy(presetTypeCopierMap) 函数的 presetTypeCopierMap 参数,如下:

const presetTypeCopierMap = new Map();
presetTypeCopierMap.set(Person,function(value,copyMember,options){let copy = new Person(value.sex);  // 创建新的 Person 实例,作为 value 的副本// 给副本 copy 设置基本类型的成员;copy.name = value.name;copy.email = value.email;// 如果引用类型的成员也需要深拷贝,则需要通过 copyMember() 函数拷贝 引用类型的成员copy.idCard = copyMember(value.idCard);/*** copyMember() 函数会返回 拷贝后的值;* 但如果被拷贝的值存在循环引用的话,copyMember() 会返回 undefined;这种情况下,可通过给 copyMember() 传递回调函数(第2个参数),通过回调函数来获取拷贝后的值;* 无论是否存在循环引用,通过回调函数总能拿到拷贝后的值,回调函数是一种保险的方法*/copyMember(value.mate,function(mateCopy){copy.mate = mateCopy;});// 需要将副本返回;return copy;
});// deepCopy2 为新的深拷贝函数,功能和 deepCopy 一样;
const deepCopy2 = createDeepCopy(presetTypeCopierMap);

其中 deepCopy2 为新的深拷贝函数,功能和 deepCopy 一样;通过 deepCopy2 来进行深拷贝操作,如下:

let copy = deepCopy2(value);

http://chatgpt.dhexx.cn/article/Bldayp1d.shtml

相关文章

深入理解Python深拷贝(deepcopy)、浅拷贝(copy)、等号拷贝----看了还不懂找我

编程中难免会遇到copy&#xff08;浅拷贝&#xff09;与deepcopy&#xff08;深拷贝&#xff09;问题&#xff0c;一不小心就会掉进坑中了&#xff0c;或许很多人只知道有深浅拷贝&#xff0c;但是你又知道copy和""拷贝有什么区别么&#xff1f;也许很少有人对二者的…

Python-copy()与deepcopy()区别

最近在实习&#xff0c;boss给布置了一个python的小任务&#xff0c;学习过程中发现copy&#xff08;&#xff09;和deepcopy&#xff08;&#xff09;这对好基友实在是有点过分&#xff0c;搞的博主就有点傻傻分不清啊&#xff0c;但是呢本着一探到底的精神&#xff0c;还是要…

三分钟入门大数据之什么是用户画像?

哈喽&#xff0c;大家好&#xff0c;我是汉斯老师。近几年来&#xff0c;互联网行业由于较高的薪资收入&#xff0c;受到许多人的追捧。很多年轻的学子&#xff0c;或是其他行业的有志青年&#xff0c;都想要投身到这个行业中来。然而一方面受到“互联网寒冬”的影响&#xff0…

什么是用户画像?金融行业大数据用户画像实践

金融消费者逐渐年轻化&#xff0c;80、90后成为客户主力&#xff0c;他们的消费意识和金融意识正在增强。金融服务正在从以产品为中心&#xff0c;转向以消费者为中心。所有金融行业面对的最大挑战是消费者的消费行为和消费需求的转变&#xff0c;金融企业迫切需要为产品寻找目…

银行用户画像简介

当我们讨论产品、需求、场景、用户体验时&#xff0c;往往需要将焦点聚集在某类人群上&#xff0c;用户画像便是一种抽象的方法&#xff0c;是目标用户的集合。本文作者对银行用户画像体系的建设进行了分析&#xff0c;希望能给你带来一些帮助。 用户画像的正式英文名称是User …

用户画像基础之用户画像是什么

目录 0. 相关文章链接 1. 用户画像是什么 2. 画像简介 3. 标签类型 注&#xff1a;此博文为根据 赵宏田 老师的 用户画像方法论与工程化解决方案 一书读后笔记而来&#xff0c;仅供学习使用 0. 相关文章链接 用户画像文章汇总 1. 用户画像是什么 在互联网步入大数据时代…

详解用户画像

01画像简介 用户画像&#xff0c;即用户信息标签化&#xff0c;通过收集用户的社会属性、消费习惯、偏好特征等各个维度的数据&#xff0c;进而对用户或者产品特征属性进行刻画&#xff0c;并对这些特征进行分析、统计&#xff0c;挖掘潜在价值信息&#xff0c;从而抽象出用户的…

用户画像——什么是用户画像?和用户画像的计算框架选型

用户画像——什么是用户画像&#xff1f;和用户画像的计算框架选型 1.什么是用户画像&#xff1f; 1.1 应用场景 1.1.1 精细化运营 1.1.2 推荐系统 1.2 概念定义 1.2.1 总结场景对数据的需求 1.2.2 实现这些场的数据结构 1.2.3 用户画像的概念 2.用户画像…

什么是用户画像,流程、方法是什么?

什么是用户画像&#xff0c;流程、方法是什么? 01 用户画像概述1. 什么是用户画像2. 为什么需要用户画像 02 用户画像流程1. 整体流程1&#xff09;目标分析2&#xff09;标签体系构建3&#xff09;画像构建 2. 标签体系1&#xff09;事实标签2&#xff09;模型标签3&#xff…

一文让你彻底明白,到底什么是用户画像?

写在前面&#xff1a; 博主是一名大数据的初学者&#xff0c;昵称来源于《爱丽丝梦游仙境》中的Alice和自己的昵称。作为一名互联网小白&#xff0c;写博客一方面是为了记录自己的学习历程&#xff0c;一方面是希望能够帮助到很多和自己一样处于起步阶段的萌新。由于水平有限&a…

什么是用户画像——从零开始搭建实时用户画像(一)

用户画像 简介 用户画像&#xff0c;作为一种勾画目标用户、联系用户诉求与设计方向的有效工具&#xff0c;用户画像在各领域得到了广泛的应用。 用户画像最初是在电商领域得到应用的&#xff0c;在大数据时代背景下&#xff0c;用户信息充斥在网络中&#xff0c;将用户的每…

帮你更好地了解什么是用户画像

用户画像是一个挺新颖的词,最初它是大数据行业言必及之的时髦概念。现在我们运营谈及用户画像,它也是和精准营销、精细化运营直接钩挂的。 什么是用户画像? 在中文的语言环境中,用户画像是用来描述用户特征(用户背景、特征、性格标签、行为场景等)和联系用户需求与产品…

什么是用户画像,用户画像的作用是什么?

更多行业干货,上网易游戏学院app查看! https://game.academy.163.com/ssi/app/?referrer=niuke 什么是用户画像? 用户画像,由交互大师艾伦库伯在他的著作《交互设计精髓4》(《AboutFace 4》)中提出。他在书中介绍:“用户画像来源于研究中真实用户的行为和动机。用户画…

什么是用户画像?如何构建用户画像?

我们通过这篇文章&#xff0c;介绍我们理解的两种用户画像&#xff08;User Persona 和 User Profile&#xff09;&#xff0c;以及如何构建用户画像&#xff08;User Profile&#xff09;的标签体系并驱动产品智能。 User Persona 第一种用户画像&#xff08;User Persona&a…

用户画像(一)

本文转自&#xff1a;用户画像实践篇 终于有人把用户画像的流程、方法讲明白了 1 什么是用户画像 1. 1 概述 通过分析用户的基础信息、特征偏好、社会属性等各维度的数据&#xff0c;刻画出用户的信息全貌&#xff0c; 从中挖掘用户价值&#xff0c;从而提供个性化推荐、精准…

什么是真正的用户画像

如今在这个大数据时代&#xff0c;每个用户都被标签化&#xff0c;运用用户画像的方式了解用户&#xff0c;从而推送相关消息&#xff1b;最常见的情况就是你买了商品后&#xff0c;推荐会自动推送与此商品相关的商品&#xff0c;促进消费&#xff1b;本文作者分享了关于什么是…

用户画像:概述【从应用角度来看,可以分为行为画像、健康画像、企业信用画像、个人信用画像、静态产品画像、旋转设备画像、社会画像、经济画像...】

一、 什么是用户画像 用户画像是指根据用户的属性、用户偏好、生活习惯、用户行为等信息而抽象出来的标签化用户模型。通俗说就是给用户打标签&#xff0c;而标签是通过对用户信息分析而来的高度精炼的特征标识。通过打标签可以利用一些高度概括、容易理解的特征来描述用户&…

对话机器人---智能客服

https://blog.csdn.net/qq_40027052/article/details/78723576 详细的介绍了对话机器人涉及到的所有知识和技术。 整个对话机器人涉及到的知识点&#xff0c;本人属于自然语言处理的研究方向&#xff0c;所以还要很多需要学习的地方。 在实现一个对话机器人的过程中&#xff0c…

安排,Mysql入门到精通教程

来源&#xff1a; 来自网络&#xff0c;如侵权请告知博主删除????。 仅学习使用&#xff0c;请勿用于其他&#xff5e; spring&#xff0c;vue的&#xff0c;前后端的都给童鞋安排过一些了&#xff0c;有童鞋让我安排Mysql了&#xff0c;走起 目录: 课时1:Mysql介绍.mp4课…