浅谈js代码的封装方法(2023.10.30)

需求

        许多企业的技术团队和个人开发者为了将自身的技术进行展现,将技术和算法实现的源码进行封装进而以类库和SDK的方式提供给客户使用,也算作一种解决方案,同时封装的类库或SDK也可对需求方进行量身定制、按需分发、按次调用或按周期计费,进而催生出现代化、便捷化、可插拔、高耦合的服务提供和响应模式。

1、js代码封装的优缺点

        正如科技是一把双刃剑js代码封装自然在带来优势的同时难免会伴随一些劣势,二者之间的平衡取决于供应方和需求方在易用性、高效性、便捷性和版本升级等方面的可接受度极限容忍度

        js代码封装的优点如下:
(1)代码量变小;
(2)提高js类库代码文件的网络传输速度;
(3)保护代码提供方的知识产权或者劳动成果;
(4)增强对源码的保护,某种程度上可提高安全性。

        js代码封装的缺点如下
(1)可读性变差;
(2)需进行定期维护或升级更新版本来加入新功能,以此导致用户为使用新功能被动升级;
(3)SDK或类库升级按理应当兼容之前发布的版本;
(4)需提供友好易懂的API调用手册和说明文档,以供用户进行参考。

2、js代码封装方式

        通常来说,一个功能或一组属性及方法的封装皆可采用function(函数)和class(类)来实现,但值得注意的是:函数声明和类声明之间的一个重要区别是,虽然函数可以在定义之前出现的代码中调用,但类必须在构造之前定义。如果小伙伴们对相关的理论知识感兴趣,建议阅读相关规范和官方文档,可参考ECMAScript Language Specification
在这里插入图片描述

2.1 方式一:function function declarations

2.1.1 示例

function square(number) {
    
    
  return number * number;
}

const square = function (number) {
    
    
  return number * number;
}
const x = square(4); // x gets the value 16

const factorial = function fac(n) {
    
    
  return n < 2 ? 1 : n * fac(n - 1);
}

console.log(factorial(3))
function map(f, a) {
    
    
  const result = new Array(a.length);
  for (let i = 0; i < a.length; i++) {
    
    
    result[i] = f(a[i]);
  }
  return result;
}

const f = function (x) {
    
    
  return x * x * x;
}

const numbers = [0, 1, 2, 5, 10];
const cube = map(f, numbers);
console.log(cube);
// A nested function example
function getScore() {
    
    
  const num1 = 2;
  const num2 = 3;

  function add() {
    
    
    return `${
      
      name} scored ${
      
      num1 + num2}`;
  }

  return add();
}

getScore(); // Returns "Chamakh scored 5"
function addSquares(a, b) {
    
    
  function square(x) {
    
    
    return x * x;
  }
  return square(a) + square(b);
}
const a = addSquares(2, 3); // returns 13
const b = addSquares(3, 4); // returns 25
const c = addSquares(4, 5); // returns 41

function A(x) {
    
    
  function B(y) {
    
    
    function C(z) {
    
    
      console.log(x + y + z);
    }
    C(3);
  }
  B(2);
}
A(1); // Logs 6 (which is 1 + 2 + 3)

const pet = function (name) {
    
       // The outer function defines a variable called "name"
  const getName = function () {
    
    
    // The inner function has access to the "name" variable of the outer function
    return name;
  }
  return getName; // Return the inner function, thereby exposing it to outer scopes
}
const myPet = pet('Vivie');

myPet(); // Returns "Vivie"
const createPet = function (name) {
    
    
  let sex;

  const pet = {
    
    
    // setName(newName) is equivalent to setName: function (newName)
    // in this context
    setName(newName) {
    
    
      name = newName;
    },

    getName() {
    
    
      return name;
    },

    getSex() {
    
    
      return sex;
    },

    setSex(newSex) {
    
    
      if (typeof newSex === 'string' &&
        (newSex.toLowerCase() === 'male' || newSex.toLowerCase() === 'female')) {
    
    
        sex = newSex;
      }
    }
  };

  return pet;
}

const pet = createPet('Vivie');
pet.getName();                  // Vivie

pet.setName('Oliver');
pet.setSex('male');
pet.getSex();                   // male
pet.getName();                  // Oliver
const a = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

const a2 = a.map(function(s) {
    
     return s.length; });

console.log(a2); // [8, 6, 7, 9]

const a3 = a.map((s) => s.length);

console.log(a3); // [8, 6, 7, 9]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

在这里插入图片描述

const multiply = new Function('x', 'y', 'return x * y');

function multiply(x, y) {
    
    
  return x * y;
} // there is no semicolon here

const multiply = function (x, y) {
    
    
  return x * y;
};

const multiply = function funcName(x, y) {
    
    
  return x * y;
};


foo(); // Logs "FOO!"
function foo() {
    
    
  console.log('FOO!');
}
// function declaration
function foo() {
    
    }

// function expression
(function bar() {
    
    })

// function expression
x = function hello() {
    
    }

if (x) {
    
    
  // function expression
  function world() {
    
    }
}

// function declaration
function a() {
    
    
  // function declaration
  function b() {
    
    }
  if (0) {
    
    
    // function expression
    function c() {
    
    }
  }
}
'use strict';

function f() {
    
    
  return 1;
}

{
    
    
  function f() {
    
    
    return 2;
  }
}

f() === 1; // true

// f() === 2 in non-strict mode
// This function returns a string padded with leading zeros
function padZeros(num, totalLen) {
    
    
  let numStr = num.toString();             // Initialize return value as string
  const numZeros = totalLen - numStr.length; // Calculate no. of zeros
  for (let i = 1; i <= numZeros; i++) {
    
    
    numStr = `0${
      
      numStr}`;
  }
  return numStr;
}


if (typeof window.noFunc === 'function') {
    
    
  // use noFunc()
} else {
    
    
  // do something else
}
class Point {
    
    
  constructor(x, y) {
    
    
    this.x = x;
    this.y = y;
  }

  static displayName = "Point";
  static distance(a, b) {
    
    
    const dx = a.x - b.x;
    const dy = a.y - b.y;

    return Math.hypot(dx, dy);
  }
}

const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance;    // undefined
p2.displayName; // undefined
p2.distance;    // undefined

console.log(Point.displayName);      // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755

2.2 方式二:class

对于一个class而言,constructor有且仅有一个,
Static initialization blocks
Prototype methods

2.2.1 class declarations

class Rectangle {
    
    
  constructor(height, width) {
    
    
    this.height = height;
    this.width = width;
  }
}

class Rectangle {
    
    
  height = 0;
  width;
  constructor(height, width) {
    
    
    this.height = height;
    this.width = width;
  }
}

class Rectangle {
    
    
  #height = 0;
  #width;
  constructor(height, width) {
    
    
    this.#height = height;
    this.#width = width;
  }
}

class Polygon {
    
    
  constructor(...sides) {
    
    
    this.sides = sides;
  }
  // Method
  *getSides() {
    
    
    for (const side of this.sides) {
    
    
      yield side;
    }
  }
}

const pentagon = new Polygon(1,2,3,4,5);

console.log([...pentagon.getSides()]); // [1,2,3,4,5]

2.2.2 Class expressions

// unnamed
let Rectangle = class {
    
    
  constructor(height, width) {
    
    
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name); // "Rectangle"

// named
Rectangle = class Rectangle2 {
    
    
  constructor(height, width) {
    
    
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name); // "Rectangle2"
class Animal {
    
    
  constructor(name) {
    
    
    this.name = name;
  }

  speak() {
    
    
    console.log(`${
      
      this.name} makes a noise.`);
  }
}

class Dog extends Animal {
    
    
  constructor(name) {
    
    
    super(name); // call the super class constructor and pass in the name parameter
  }

  speak() {
    
    
    console.log(`${
      
      this.name} barks.`);
  }
}

const d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
function Animal(name) {
    
    
  this.name = name;
}

Animal.prototype.speak = function () {
    
    
  console.log(`${
      
      this.name} makes a noise.`);
}

class Dog extends Animal {
    
    
  speak() {
    
    
    console.log(`${
      
      this.name} barks.`);
  }
}

const d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
const Animal = {
    
    
  speak() {
    
    
    console.log(`${
      
      this.name} makes a noise.`);
  }
};

class Dog {
    
    
  constructor(name) {
    
    
    this.name = name;
  }
}

// If you do not do this you will get a TypeError when you invoke speak
Object.setPrototypeOf(Dog.prototype, Animal);

const d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
class Cat {
    
    
  constructor(name) {
    
    
    this.name = name;
  }

  speak() {
    
    
    console.log(`${
      
      this.name} makes a noise.`);
  }
}

class Lion extends Cat {
    
    
  speak() {
    
    
    super.speak();
    console.log(`${
      
      this.name} roars.`);
  }
}

const l = new Lion('Fuzzy');
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.

2.3 变量+函数

var r = function () {
    
    
        function e(e, t) {
    
    
            for (var i = 0; i < t.length; i++) {
    
    
                var a = t[i]; a.enumerable = a.enumerable || !1, a.configurable = !0, "value" in a && (a.writable = !0),
                    Object.defineProperty(e, a.key, a)
            }
        }
        return function (t, i, a) {
    
    
            return i && e(t.prototype, i), a && e(t, a), t
        }
    }();
   Cesium.ViewShed3D = function () {
    
    
function e(t, i) {
    
    
            n(this, e), t && (i || (i = {
    
    }),
                this.viewer = t,
                this.cameraPosition = Cesium.defaultValue(i.cameraPosition, c.cameraPosition),
                this.viewPosition = Cesium.defaultValue(i.viewPosition, c.viewPosition),
                this._horizontalAngle = Cesium.defaultValue(i.horizontalAngle, c.horizontalAngle),
                this._verticalAngle = Cesium.defaultValue(i.verticalAngle, c.verticalAngle),
                this._visibleAreaColor = Cesium.defaultValue(i.visibleAreaColor, c.visibleAreaColor),
                this._hiddenAreaColor = Cesium.defaultValue(i.hiddenAreaColor, c.hiddenAreaColor),
                this._alpha = Cesium.defaultValue(i.alpha, c.alpha),
                this._distance = Cesium.defaultValue(i.distance, c.distance),
                this._frustum = Cesium.defaultValue(i.frustum, c.frustum),
                this.calback = i.calback, 
                this.cameraPosition && this.viewPosition ? (this._addToScene(), this.calback && this.calback()) : this._bindMourseEvent())
        }
        return r(e, [{
    
    
            key: "_bindMourseEvent",
            value: function () {
    
    
                var e = this,
                    t = this.viewer,
                    i = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
                i.setInputAction(function (i) {
    
    
                    var a = Cesium.getCurrentMousePosition(t.scene, i.position);
                    a && (e.cameraPosition ? e.cameraPosition && !e.viewPosition && (e.viewPosition = a,
                        e._addToScene(), e._unbindMourseEvent(), e.calback && e.calback()) : e.cameraPosition = a)
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK), 
                i.setInputAction(function (i) {
    
    
                    var a = Cesium.getCurrentMousePosition(t.scene, i.endPosition);
                    if (a) {
    
    
                        var n = e.cameraPosition; n && (e.frustumQuaternion = e.getFrustumQuaternion(n, a),
                            e.distance = Number(Cesium.Cartesian3.distance(n, a).toFixed(1)))
                    }
                }, Cesium.ScreenSpaceEventType.MOUSE_MOVE),
                this._handler = i
            }
        }, {
    
    
            key: "_unbindMourseEvent",
            value: function () {
    
    
                null != this._handler && (this._handler.destroy(), delete this._handler)
            }
        },

2.4 变量+闭包+匿名函数

//获取高程
var TerrainToolCopy = (
     function () {
    
    
        
         var terrainLevel = 14;//数据等级14

         function _() {
    
    

         }

         //传入lonlat数组 角度制的lon lat
         _.LonlatPointsTerrainData = function (terrainProvider,lonlats, callback) {
    
    
             var pointArrInput = [];
             for (var i = 0; i < lonlats.length; i++) {
    
    
                 pointArrInput.push(Cesium.Cartographic.fromDegrees(lonlats[i].lon, lonlats[i].lat));
             }
             var promise = Cesium.sampleTerrain(terrainProvider, terrainLevel, pointArrInput);//pointArrInput
             Cesium.when(promise, function (updatedPositions) {
    
    
                 callback(updatedPositions);
             });
         };

         //传入Cartographic类型数组 弧度制经纬度
         _.CartographicPointsTerrainData = function (terrainProvider,Cartographics, callback) {
    
    
             if (Cartographics.length && Cartographics.length > 0) {
    
     } else {
    
     return; }
             var promise = Cesium.sampleTerrain(terrainProvider, terrainLevel, Cartographics);//pointArrInput
             Cesium.when(promise, function (updatedPositions) {
    
    
                 callback(updatedPositions);
             });
         };
         return _;
     }
)();

2.5 闭包函数

(function () {
    
    

    function n(t, e) {
    
    
        e = e || {
    
    },
            r = t.scene.globe.ellipsoid,
            this._geometry = null,
            this._angle = e.angle,
            this._radius = e.radius ? e.radius : 5,
            this._position = e.position,
            this._rotation = e.rotation ? e.rotation : {
    
    
                heading: 0,
                pitch: 0,
                roll: 0
            },
            this._trackedEntity = e.trackedEntity,
            this.defaultColor = e.color ? e.color : Cesium.Color.YELLOW,
            this.defaultLineColor = e.lineColor ? e.lineColor : this.defaultColor,
            this._show = Cesium.defaultValue(e.show, !0),
            this._outline = Cesium.defaultValue(e.outline, !1),
            this._topShow = Cesium.defaultValue(e.top, !0),
            this._topOutline = Cesium.defaultValue(e.topOutline, !0),
            this._modelMatrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY),
            this._quaternion = new Cesium.Quaternion,
            this._translation = new Cesium.Cartesian3,
            this._scale = new Cesium.Cartesian3(1, 1, 1),
            this._matrix = new Cesium.Matrix4,
            this._inverseMatrix = new Cesium.Matrix4,
            this._positionCartographic = new Cesium.Cartographic,
            this._positionCartesian = null,
            this._drawCommands = [],
            this._outlinePositions = [],
            this.viewer = t,
            this.viewer.scene.primitives.add(this),
            this.updateGeometry(),
            this._groundArea = Cesium.defaultValue(e.groundArea, !1),
            this.addGroundAreaEntity(this._groundArea)
    }
    Object.defineProperty(Cesium, "__esModule", {
    
    
        value: !0
    }),
        Cesium.RadarPrimitive = void 0;
    var r;
    Object.defineProperties(n.prototype, {
    
    
        trackedEntity: {
    
    
            get: function () {
    
    
                return this._trackedEntity
            },
            set: function (t) {
    
    
                this._trackedEntity = t
            }
        },
        color: {
    
    
            get: function () {
    
    
                return this.defaultColor
            },
            set: function (t) {
    
    
                this.defaultColor = t
            }
        },
        lineColor: {
    
    
            get: function () {
    
    
                return this.defaultLineColor
            },
            set: function (t) {
    
    
                this.defaultLineColor = t
            }
        },
        show: {
    
    
            get: function () {
    
    
                return this._show
            },
            set: function (t) {
    
    
                this._show = t
            }
        },
        outline: {
    
    
            get: function () {
    
    
                return this._outline
            },
            set: function (t) {
    
    
                this._outline = t, this.updateGeometry()
            }
        },
        top: {
    
    
            get: function () {
    
    
                return this._topShow
            },
            set: function (t) {
    
    
                this._topShow = t, this.updateGeometry()
            }
        },
        topOutline: {
    
    
            get: function () {
    
    
                return this._topOutline
            },
            set: function (t) {
    
    
                this._topOutline = t, this.updateGeometry()
            }
        },
        groundArea: {
    
    
            get: function () {
    
    
                return this._groundArea
            },
            set: function (t) {
    
    
                this._groundArea = t, this.addGroundAreaEntity(this._groundArea)
            }
        },
        angle: {
    
    
            get: function () {
    
    
                return this._angle
            },
            set: function (t) {
    
    
                this._angle = t, this.updateGroundCircleRadius(), this.updateGeometry()
            }
        },
        radius: {
    
    
            get: function () {
    
    
                return this._radius
            },
            set: function (t) {
    
    
                this._radius = t, this.updateGroundCircleRadius(), this.updateGeometry()
            }
        },
        heading: {
    
    
            get: function () {
    
    
                return this._rotation.heading
            },
            set: function (t) {
    
    
                this._rotation.heading = t
            }
        },
        pitch: {
    
    
            get: function () {
    
    
                return this._rotation.pitch
            },
            set: function (t) {
    
    
                this._rotation.pitch = t
            }
        },
        roll: {
    
    
            get: function () {
    
    
                return this._rotation.roll
            },
            set: function (t) {
    
    
                this._rotation.roll = t
            }
        },
        position: {
    
    
            get: function () {
    
    
                return this._position
            }, set: function (t) {
    
    
                this._position = t
            }
        }
    }),
        n.prototype.updateGroundCircleRadius = function () {
    
    
            this._ground_radius = this._radius * Math.cos(Cesium.Math.toRadians(this._angle))
        },
        n.prototype.addGroundAreaEntity = function (t) {
    
    
            if (t && !this.groundAreaEntity) {
    
    
                var e = this;
                this.updateGroundCircleRadius(),
                    this.groundAreaEntity = viewer.entities.add({
    
    
                        position: this._position,
                        ellipse: {
    
    
                            show: 0 === this._rotation.pitch && 0 === this._rotation.roll,
                            semiMinorAxis: new Cesium.CallbackProperty(function (t) {
    
    
                                return e._ground_radius
                            }, !1),
                            semiMajorAxis: new Cesium.CallbackProperty(function (t) {
    
    
                                return e._ground_radius
                            }, !1),
                            material: this.defaultColor
                        },
                        polyline: {
    
    
                            show: this._trackedEntityPosition && (0 !== this._rotation.pitch || 0 !== this._rotation.roll),
                            positions: new Cesium.CallbackProperty(function (t) {
    
    
                                return e._trackedEntityPosition ? Cesium.Cartesian3.distance(e._position, e._trackedEntityPosition) > e._radius ? [] : [e._position, e._trackedEntityPosition] : []
                            }, !1),
                            followSurface: !1,
                            material: new Cesium.PolylineDashMaterialProperty({
    
    
                                color: Cesium.Color.CYAN
                            }),
                            width: 1
                        }
                    })
            }
        };
    var l = new Cesium.Cartesian3;
    n.prototype.computeMatrix = function (t, e) {
    
    
        if (this._positionCartesian || (this._positionCartesian = new Cesium.Cartesian3), this.position instanceof Cesium.Cartesian3 ? this._positionCartesian = this.position : "function" == typeof this.position.getValue ? this._positionCartesian = this.position.getValue(t) : this.position._value && this.position._value instanceof Cesium.Cartesian3 && (this._positionCartesian = this.position._value), this._trackedEntity && this._trackedEntity.position) {
    
    
            var i = this._positionCartesian,
                n = Cesium.Property.getValueOrUndefined(this._trackedEntity.position, t, l);
            if (n) {
    
    
                this._trackedEntityPosition = n;
                var o = mars3d.matrix.getHeadingPitchRollForLine(i, n, r);
                this._rotation.heading = o.heading, this._rotation.pitch = o.pitch, this._rotation.roll = o.roll
            }
        }
        return this._modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(this._positionCartesian, r, this._modelMatrix),
            this._positionCartographic = Cesium.Cartographic.fromCartesian(this._positionCartesian, r, this._positionCartographic),
            Cesium.Transforms.eastNorthUpToFixedFrame(this._positionCartesian, r, this._modelMatrix),
            Cesium.Quaternion.fromHeadingPitchRoll(this._rotation, this._quaternion),
            this._matrix = Cesium.Matrix4.fromTranslationQuaternionRotationScale(this._translation, this._quaternion, this._scale, this._matrix),
            Cesium.Matrix4.multiplyTransformation(this._modelMatrix, this._matrix, this._matrix),
            Cesium.Matrix4.inverseTransformation(this._matrix, this._inverseMatrix),
            this._matrix
    },
        n.prototype.getTopGeometry = function () {
    
    
            for (var t = this.radius, e = [], i = [], n = [], r = [], o = 90 - parseInt(this.angle), s = o < 1 ? o / 8 : 1, l = 2 * Math.PI / 127, h = 0, d = this.angle; d < 91; d += s) {
    
    
                var m = Cesium.Math.toRadians(d < 90 ? d : 90);
                m = Math.cos(m) * t;
                for (var f = [], p = 0; p < 128; p++) {
    
    
                    var c = l * p,
                        _ = m * Math.cos(c),
                        g = m * Math.sin(c),
                        v = Math.sqrt(t * t - _ * _ - g * g);
                    e.push(_, g, v),
                        i.push(1, 1),
                        f.push(h++)
                }
                r.push(f)
            }
            for (var d = 1; d < r.length; d++)
                for (var p = 1; p < r[d].length; p++) {
    
    
                    var y = r[d - 1][p - 1],
                        C = r[d][p - 1],
                        w = r[d][p], x = r[d - 1][p];
                    n.push(y, C, w),
                        n.push(y, w, x)
                }
            e = new Float32Array(e),
                n = new Int32Array(n),
                i = new Float32Array(i);
            var A = {
    
    
                position: new Cesium.GeometryAttribute({
    
    
                    componentDatatype: Cesium.ComponentDatatype.DOUBLE,
                    componentsPerAttribute: 3, values: e
                }),
                st: new Cesium.GeometryAttribute({
    
     componentDatatype: Cesium.ComponentDatatype.FLOAT, componentsPerAttribute: 2, values: i })
            },
                b = Cesium.BoundingSphere.fromVertices(e),
                M = new Cesium.Geometry({
    
    
                    attributes: A,
                    indices: n,
                    primitiveType: Cesium.PrimitiveType.TRIANGLES,
                    boundingSphere: b
                });
            return (0, Cesium.computeVertexNormals)(M), M
        },
        n.prototype.getTopOutlineGeometry = function () {
    
    
            for (var t = this.radius, e = [], i = [], n = [], r = [], o = 90 - parseInt(this.angle), s = o < 1 ? o / 8 : 1, l = 2 * Math.PI / 127, h = 0, d = this.angle; d < 91; d += s) {
    
    
                var m = Cesium.Math.toRadians(d < 90 ? d : 90);
                m = Math.cos(m) * t;
                for (var f = [], p = 0; p < 128; p++) {
    
    
                    var c = l * p, _ = m * Math.cos(c), g = m * Math.sin(c), v = Math.sqrt(t * t - _ * _ - g * g);
                    e.push(_, g, v), i.push(1, 1), f.push(h++)
                }
                r.push(f)
            }
            for (var d = 1; d < r.length; d++)
                for (var p = 1; p < r[d].length; p++) {
    
    
                    var y = r[d - 1][p - 1], C = r[d][p - 1], w = r[d][p]; r[d - 1][p];
                    p % 8 == 1 && n.push(y, C), d % 8 == 1 && n.push(C, w)
                }
            e = new Float32Array(e), n = new Int32Array(n), i = new Float32Array(i);
            var x = {
    
    
                position: new Cesium.GeometryAttribute({
    
    
                    componentDatatype: Cesium.ComponentDatatype.DOUBLE,
                    componentsPerAttribute: 3,
                    values: e
                }),
                st: new Cesium.GeometryAttribute({
    
    
                    componentDatatype: Cesium.ComponentDatatype.FLOAT,
                    componentsPerAttribute: 2, values: i
                })
            },
                A = Cesium.BoundingSphere.fromVertices(e),
                b = new Cesium.Geometry({
    
    
                    attributes: x,
                    indices: n,
                    primitiveType: Cesium.PrimitiveType.LINES,
                    boundingSphere: A
                });
            return (0, Cesium.computeVertexNormals)(b), b
        },
        n.prototype.updateGeometry = function () {
    
    
            this._geometry = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
    
    
                topRadius: this._radius * Math.cos(Cesium.Math.toRadians(this.angle)),
                bottomRadius: 0,
                length: this._radius * Math.sin(Cesium.Math.toRadians(this.angle))
            })),
                this._topGeometry = this.getTopGeometry(),
                this._topOutlineGeometry = this.getTopOutlineGeometry(),
                this._outlineGeometry = Cesium.CylinderGeometry.createOutlineGeometry(new Cesium.CylinderGeometry({
    
    
                    topRadius: this._radius * Math.cos(Cesium.Math.toRadians(this.angle)), 
                    bottomRadius: 0, 
                    slices: 128, 
                    length: this._radius * Math.sin(Cesium.Math.toRadians(this.angle))
                })),
                this._positions = new Float32Array(this._geometry.attributes.position.values.length);
            for (var t = 0; t < this._positions.length; t++)this._positions[t] = this._geometry.attributes.position.values[t];
            this._drawCommands && this._drawCommands.length && (this._drawCommands.forEach(function (t) {
    
    
                t.vertexArray = t.vertexArray && t.vertexArray.destroy()
            }),
                this._drawCommands.splice(0, this._drawCommands.length))
        },
        n.prototype.update = function (t) {
    
    
            if (this._show) {
    
    
                this.computeMatrix(t.time);
                t.mode === Cesium.SceneMode.SCENE3D ? (this._geometry.boundingSphere = Cesium.BoundingSphere.fromVertices(this._geometry.attributes.position.values), this._drawCommands && this._drawCommands.length || (this._drawCommands.push(this.createDrawCommand(this._geometry, t)), this._outline && this._drawCommands.push(this.createDrawCommand(this._outlineGeometry, t)), this._topShow && (this._drawCommands.push(this.createDrawCommand(this._topGeometry, t)),
                    this._topOutline && this._drawCommands.push(this.createDrawCommand(this._topOutlineGeometry, t)))), this._drawCommands.forEach(function (e) {
    
     t.commandList.push(e) }), this.groundAreaEntity && (this.groundAreaEntity.ellipse.show = this._groundArea && 0 === this._rotation.pitch && 0 === this._rotation.roll, this.groundAreaEntity.polyline.show = !1)) : (this.groundAreaEntity || this.addGroundAreaEntity(!0), this.groundAreaEntity.ellipse.show = 0 === this._rotation.pitch && 0 === this._rotation.roll, this.groundAreaEntity.polyline.show = this._trackedEntityPosition && (0 !== this._rotation.pitch || 0 !== this._rotation.roll))
            }
        },
        n.prototype.getFragmentShaderSource = function (t) {
    
    
            return "\nvarying vec3 v_position;\nvarying vec3 v_normal;\nuniform float picked;\nuniform vec4  pickedColor;\nuniform vec4  defaultColor;\nuniform float specular;\nuniform float shininess;\nuniform vec3  emission;\nvarying vec2 v_st;\nuniform bool isLine;\nuniform float glowPower;\nvoid main() {\n    vec3 positionToEyeEC = -v_position; \n    vec3 normalEC =normalize(v_normal);\n    vec4 color=defaultColor;\n    if(picked!=0.0){\n        color = pickedColor;\n    }\n    //if(v_st.x<0.5){\n    //    color.a =0.75-v_st.x; \n    //}\n    //else  {\n    //    color.a =v_st.x-0.25; \n    //}\n    czm_material material;\n    material.specular = specular;\n    material.shininess = shininess;\n    material.normal =  normalEC;\n    material.emission =emission;//vec3(0.2,0.2,0.2);\n    material.diffuse = color.rgb ;\n    if(isLine){\n        material.alpha = 1.0; \n    }\n    else{\n        material.alpha =  color.a; \n    }\n        //float glow = glowPower / abs(v_st.t  ) - (glowPower / 0.5); \n        // \n        //material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb); \n        //if(isLine)\n        //    material.alpha = clamp(0.0, 1.0, glow) * color.a; \n         \n    if(v_st.x==0.0){ \n          gl_FragColor =color ;\n    }else { \n        gl_FragColor = czm_phong(normalize(positionToEyeEC), material) ; \n    } \n}"
        },
        n.prototype.getVertexShaderSource = function (t) {
    
    
            return "\n#ifdef GL_ES\n    precision highp float;\n#endif\n\nattribute vec3 position;\nattribute vec2 st;\nattribute vec3 normal;\nuniform mat4 modelViewMatrix;\nuniform mat3 normalMatrix;\nuniform mat4 projectionMatrix;\nvarying vec3 v_position;\nvarying vec3 v_normal;\nvarying vec2 v_st;\n\nvarying vec3 v_light0Direction;\n\nvoid main(void) \n{\n    vec4 pos =  modelViewMatrix * vec4( position,1.0);\n    v_normal =  normalMatrix *  normal;\n    v_st = st;\n    v_position = pos.xyz;\n    v_light0Direction = mat3( modelViewMatrix) * vec3(1.0,1.0,1.0);\n    gl_Position =  projectionMatrix * pos;\n}"
        },
        n.prototype.createDrawCommand = function (t, e, i) {
    
    
            var n = e.context, r = new Cesium.Cartesian3; Cesium.Matrix4.multiplyByPoint(this._matrix, t.boundingSphere.center, r);
            var o = new Cesium.BoundingSphere(r, t.boundingSphere.radius), s = new Cesium.DrawCommand({
    
    
                modelMatrix: i || this._matrix,
                owner: this,
                primitiveType: t.primitiveType,
                pass: Cesium.Pass.TRANSLUCENT,
                boundingVolume: o
            }),
                u = this, l = Cesium.GeometryPipeline.createAttributeLocations(t);
            return s.vertexArray = Cesium.VertexArray.fromGeometry({
    
    
                context: n,
                geometry: t,
                attributeLocations: l,
                bufferUsage: Cesium.BufferUsage.STATIC_DRAW
            }),
                s.vertexArray._attributeLocations = l,
                s.shaderProgram = Cesium.ShaderProgram.replaceCache({
    
    
                    context: n,
                    vertexShaderSource: this.getVertexShaderSource(t),
                    fragmentShaderSource: this.getFragmentShaderSource(t),
                    attributeLocations: l
                }),
                s.renderState = Cesium.RenderState.fromCache({
    
    
                    blending: Cesium.BlendingState.ALPHA_BLEND,
                    depthTest: {
    
    
                        enabled: !0,
                        func: Cesium.DepthFunction.LESS
                    },
                    cull: {
    
    
                        enabled: !1,
                        face: Cesium.CullFace.BACK
                    }
                }),
                s.uniformMap = {
    
    }, s.uniformMap.projectionMatrix = function () {
    
    
                    return e.context.uniformState.projection
                },
                s.uniformMap.modelViewMatrix = function () {
    
    
                    return e.context.uniformState.modelView
                },
                s.uniformMap.shininess = function () {
    
    
                    return u.shininess || (u.shininess = 0), u.shininess
                },
                s.uniformMap.emission = function () {
    
    
                    return u.emission || (u.emission = new Cesium.Cartesian3(.2, .2, .2)), u.emission
                },
                s.uniformMap.specular = function () {
    
    
                    return u.specular || (u.specular = 0), u.specular
                },
                s.uniformMap.isLine = function () {
    
    
                    return t.primitiveType == Cesium.PrimitiveType.LINES || t.primitiveType == Cesium.PrimitiveType.LINE_STRIP
                },
                s.uniformMap.defaultColor = function () {
    
    
                    return t.primitiveType == Cesium.PrimitiveType.LINES || t.primitiveType == Cesium.PrimitiveType.LINE_STRIP ? (u.defaultLineColor || (u.defaultLineColor = new Cesium.Color(1, 1, 0, 1)), u.defaultLineColor) : (u.defaultColor || (u.defaultColor = new Cesium.Color(1, 0, 0, 1)), u.defaultColor)
                },
                s.uniformMap.picked = function () {
    
    
                    return u.picked || (u.picked = 0), u.picked
                },
                s.uniformMap.pickedColor = function () {
    
    
                    return u.pickedColor || (u.pickedColor = new Cesium.Color(1, 1, 0, 1)), u.pickedColor
                },
                s.uniformMap.normalMatrix = function () {
    
    
                    return e.context.uniformState.normal
                },
                s.uniformMap.glowPower = function () {
    
    
                    return .25
                },
                s
        },
        n.prototype.remove = function () {
    
    
            this.viewer.scene.primitives.remove(this), this.groundAreaEntity && this.viewer.entities.remove(this.groundAreaEntity)
        },
        n.prototype.addToScene = function () {
    
    
            this.viewer.scene.primitives.add(this), this.groundAreaEntity && this.viewer.entities.add(this.groundAreaEntity)
        },
        n.prototype.destroy = function (t) {
    
    
            t && (this.viewer.scene.primitives.remove(this), this.groundAreaEntity && this.viewer.entities.remove(this.groundAreaEntity), this._drawCommands.forEach(function (t) {
    
    
                t.vertexArray = t.vertexArray && t.vertexArray.destroy()
            }), this._drawCommands = [])
        },
        Cesium.RadarPrimitive = n

})()

2.6 变量+闭包+内部变量函数

var EllipseGeometryLibraryEx = (function () {
    
    
    var EllipseGeometryLibrary = {
    
    };

    var rotAxis = new Cesium.Cartesian3();
    var tempVec = new Cesium.Cartesian3();
    var unitQuat = new Cesium.Quaternion();
    var rotMtx = new Cesium.Matrix3();

    function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) {
    
    
        var azimuth = theta + rotation;

        Cesium.Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
        Cesium.Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
        Cesium.Cartesian3.add(rotAxis, tempVec, rotAxis);

        var cosThetaSquared = Math.cos(theta);
        cosThetaSquared = cosThetaSquared * cosThetaSquared;

        var sinThetaSquared = Math.sin(theta);
        sinThetaSquared = sinThetaSquared * sinThetaSquared;

        var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
        var angle = radius / mag;

        // Create the quaternion to rotate the position vector to the boundary of the ellipse.
        Cesium.Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
        Cesium.Matrix3.fromQuaternion(unitQuat, rotMtx);

        Cesium.Matrix3.multiplyByVector(rotMtx, unitPos, result);
        Cesium.Cartesian3.normalize(result, result);
        Cesium.Cartesian3.multiplyByScalar(result, mag, result);
        return result;
    }

    var scratchCartesian1 = new Cesium.Cartesian3();
    var scratchCartesian2 = new Cesium.Cartesian3();
    var scratchCartesian3 = new Cesium.Cartesian3();
    var scratchNormal = new Cesium.Cartesian3();
    /**
     * Returns the positions raised to the given heights
     * @private
     */
    EllipseGeometryLibrary.raisePositionsToHeight = function (positions, options, extrude) {
    
    
        var ellipsoid = options.ellipsoid;
        var height = options.height;
        var extrudedHeight = options.extrudedHeight;
        var size = (extrude) ? positions.length / 3 * 2 : positions.length / 3;

        var finalPositions = new Float64Array(size * 3);

        var length = positions.length;
        var bottomOffset = (extrude) ? length : 0;
        for (var i = 0; i < length; i += 3) {
    
    
            var i1 = i + 1;
            var i2 = i + 2;

            var position = Cesium.Cartesian3.fromArray(positions, i, scratchCartesian1);
            ellipsoid.scaleToGeodeticSurface(position, position);

            var extrudedPosition = Cesium.Cartesian3.clone(position, scratchCartesian2);
            var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);
            var scaledNormal = Cesium.Cartesian3.multiplyByScalar(normal, height, scratchCartesian3);
            Cesium.Cartesian3.add(position, scaledNormal, position);

            if (extrude) {
    
    
                Cesium.Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal);
                Cesium.Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition);

                finalPositions[i + bottomOffset] = extrudedPosition.x;
                finalPositions[i1 + bottomOffset] = extrudedPosition.y;
                finalPositions[i2 + bottomOffset] = extrudedPosition.z;
            }

            finalPositions[i] = position.x;
            finalPositions[i1] = position.y;
            finalPositions[i2] = position.z;
        }

        return finalPositions;
    };

    var unitPosScratch = new Cesium.Cartesian3();
    var eastVecScratch = new Cesium.Cartesian3();
    var northVecScratch = new Cesium.Cartesian3();
    /**
     * options.semiMinorAxis:短半轴
     * options.semiMajorAxis:长半轴
     * options.rotation:旋转角度 弧度
     * options.center:中心点 笛卡尔坐标
     * options.granularity:粒度 弧度
       addFillPositions:是否插值
       addEdgePositions:是否添加端点
     * Returns an array of positions that make up the ellipse.
     * @private
     */
    EllipseGeometryLibrary.computeEllipsePositions = function (options, addEdgePositions) {
    
    
        var semiMinorAxis = options.semiMinorAxis;
        var semiMajorAxis = options.semiMajorAxis;
        var rotation = options.rotation;//法线
        var center = options.center;
        var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
        if (granularity > Math.PI / 12.0) {
    
     granularity = Math.PI / 12.0; }
        if (granularity < Math.PI / 180.0) {
    
     granularity = Math.PI / 180.0; }
        var aSqr = semiMinorAxis * semiMinorAxis;
        var bSqr = semiMajorAxis * semiMajorAxis;
        var ab = semiMajorAxis * semiMinorAxis;

        var mag = Cesium.Cartesian3.magnitude(center);//模

        var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
        var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
        eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
        var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
        var numPts = 1 + Math.ceil(Cesium.Math.PI_OVER_TWO / granularity);

        var deltaTheta = Cesium.Math.PI_OVER_TWO / (numPts - 1);
        var theta = Cesium.Math.PI_OVER_TWO - numPts * deltaTheta;
        if (theta < 0.0) {
    
    
            numPts -= Math.ceil(Math.abs(theta) / deltaTheta);
        }
        var positions = new Array((numPts + 1) * 3);
        var positionsdown = new Array((numPts + 1) * 3);

        var positionIndex = 0;
        var positionsdownIndex = 0;
        var position = scratchCartesian1;
        var reflectedPosition = scratchCartesian2;

        var outerPositionsLength = (numPts * 4) * 3;
        var outerRightIndex = outerPositionsLength - 1;
        var outerLeftIndex = 0;
        var outerPositions = (addEdgePositions) ? new Array(outerPositionsLength) : undefined;

        var i;
        var j;
        var numInterior;
        var t;
        var interiorPosition;

        theta = Cesium.Math.PI_OVER_TWO;
        position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
        positions[positionIndex++] = position.x;
        positions[positionIndex++] = position.y;
        positions[positionIndex++] = position.z;
        if (addEdgePositions) {
    
    
            outerPositions[outerRightIndex--] = position.z;
            outerPositions[outerRightIndex--] = position.y;
            outerPositions[outerRightIndex--] = position.x;
        }

        theta = Cesium.Math.PI_OVER_TWO - deltaTheta;
        for (i = 1; i < numPts + 1; ++i) {
    
    
            position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
            reflectedPosition = pointOnEllipsoid(Math.PI - theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
            positionsdown[positionsdownIndex++] = position.x;
            positionsdown[positionsdownIndex++] = position.y;
            positionsdown[positionsdownIndex++] = position.z;
            positions[positionIndex++] = reflectedPosition.x;
            positions[positionIndex++] = reflectedPosition.y;
            positions[positionIndex++] = reflectedPosition.z;
            if (addEdgePositions) {
    
    
                outerPositions[outerRightIndex--] = position.z;
                outerPositions[outerRightIndex--] = position.y;
                outerPositions[outerRightIndex--] = position.x;
                outerPositions[outerLeftIndex++] = reflectedPosition.x;
                outerPositions[outerLeftIndex++] = reflectedPosition.y;
                outerPositions[outerLeftIndex++] = reflectedPosition.z;
            }

            theta = Cesium.Math.PI_OVER_TWO - (i + 1) * deltaTheta;
        }
        for (i = numPts; i > 1; --i) {
    
    
            theta = Cesium.Math.PI_OVER_TWO - (i - 1) * deltaTheta;

            position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
            reflectedPosition = pointOnEllipsoid(theta + Math.PI, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, reflectedPosition);
            positionsdown[positionsdownIndex++] = position.x;
            positionsdown[positionsdownIndex++] = position.y;
            positionsdown[positionsdownIndex++] = position.z;
            positions[positionIndex++] = reflectedPosition.x;
            positions[positionIndex++] = reflectedPosition.y;
            positions[positionIndex++] = reflectedPosition.z;
            if (addEdgePositions) {
    
    
                outerPositions[outerRightIndex--] = position.z;
                outerPositions[outerRightIndex--] = position.y;
                outerPositions[outerRightIndex--] = position.x;
                outerPositions[outerLeftIndex++] = reflectedPosition.x;
                outerPositions[outerLeftIndex++] = reflectedPosition.y;
                outerPositions[outerLeftIndex++] = reflectedPosition.z;
            }
        }

        theta = Cesium.Math.PI_OVER_TWO;
        position = pointOnEllipsoid(-theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);

        var r = {
    
    };
        positionsdown[positionsdownIndex++] = position.x;
        positionsdown[positionsdownIndex++] = position.y;
        positionsdown[positionsdownIndex++] = position.z;

        r.positions = positions;
        r.positionsdown = positionsdown;
        r.numPts = numPts;
        if (addEdgePositions) {
    
    
            outerPositions[outerRightIndex--] = position.z;
            outerPositions[outerRightIndex--] = position.y;
            outerPositions[outerRightIndex--] = position.x;
            r.outerPositions = outerPositions;
        }
        return r;
    };

    /**
    * options.semiMinorAxis:短半轴
    * options.semiMajorAxis:长半轴
    * options.rotation:旋转角度 弧度
    * options.center:中心点 笛卡尔坐标
    * options.granularity:粒度 弧度
    * Returns an array of positions that make up the ellipse.
    * @private
    */
    EllipseGeometryLibrary.computeEllipseEdgePositions = function (options) {
    
    
        var semiMinorAxis = options.semiMinorAxis;
        var semiMajorAxis = options.semiMajorAxis;
        var rotation = options.rotation;//法线
        var center = options.center;
        var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度间隔
        if (granularity > Math.PI / 12.0) {
    
     granularity = Math.PI / 12.0; }
        if (granularity < Math.PI / 180.0) {
    
     granularity = Math.PI / 180.0; }
        var aSqr = semiMinorAxis * semiMinorAxis;
        var bSqr = semiMajorAxis * semiMajorAxis;
        var ab = semiMajorAxis * semiMinorAxis;
        var mag = Cesium.Cartesian3.magnitude(center);//
        var unitPos = Cesium.Cartesian3.normalize(center, unitPosScratch);
        var eastVec = Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Z, center, eastVecScratch);
        eastVec = Cesium.Cartesian3.normalize(eastVec, eastVec);
        var northVec = Cesium.Cartesian3.cross(unitPos, eastVec, northVecScratch);
        var numPts = Math.ceil(Cesium.Math.PI * 2 / granularity);
        var deltaTheta = granularity;
        var theta = 0;

        var position = scratchCartesian1;
        var i;
        var outerIndex = 0;
        var outerPositions = [];
        for (i = 0; i < numPts; i++) {
    
    
            theta = i * deltaTheta;
            position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);

            outerPositions[outerIndex++] = position.x;
            outerPositions[outerIndex++] = position.y;
            outerPositions[outerIndex++] = position.z;
        }

        var r = {
    
    };
        r.numPts = numPts;
        r.outerPositions = outerPositions;
        return r;
    };
    return EllipseGeometryLibrary;
})();

3、匿名函数间接调用执行方法

        同时,封装的js代码为了避免用户根据API函数名称搜索或定位代码位置,因此就存在匿名函数来帮助解决这一困扰,匿名函数也称无名函数,顾明思义不需要为函数起名,因此也就具有高隐蔽性、定位难度大、作用域有限、封闭性强等特点,加之匿名函数可层层嵌套,较难捕捉,一定程度上有利于对代码安全的保护。

(function (){
    
    console.log('jjg')}())
!function(a,b){
    
    console.log(a+b);}('hello','world')
eval('function print(a){console.log(a);}\x20print(`jjg`)')

(function(){
    
    console.log('jing_zhong')})()

4、小结

        逝者如斯,日月如梭。转眼间已经接触FrontEndWebGIS开发一年有余,与许多技术娴熟、经验丰富的前辈接触,深表敬佩,感慨颇丰,在面对复杂、繁琐、大型的实战项目页面应用开发任务时,除了从互联网上寻找相关资料和博客文章中借鉴代码示例,更多地从他们的身上学到了面对问题时的沉着冷静、从容不迫、临危不惧、化难为易、深入浅出、巧妙应对,其实许多挑战往往都能够迎刃而解,善于求助是强者的行为,开放平等的交流能够积极促进对话,进而相互探讨、理解、共同思考,众人拾柴火焰高,独乐乐不如众乐乐,积极地分享知识、技术、经验和技巧给志同道合、兴趣相投的好友,实乃人生一大乐事,正所谓知音难觅,知己难求,在当下物欲横流、飞速发展的社会,希望每个人都能寻找到自己的佳音,互相扶持,相伴一生。(注:尽管本文介绍自己所看到的js封装的几种方法,旨在与广大开发者、技术爱好者共同探讨分享,严禁随意用于商业用途!!!作者本人从内心深处热爱开源、力促开源,希望为开源贡献绵薄之力,封闭必然导致落后自大,开源代表开放合作,知识共享,伟大的人类同处地球村,是一个命运共同体,应该通力合作,优势互补,取长补短,共同进步,不断推动人类的进步与繁荣

        与此同时,不免感慨,不禁赞叹:正如高手在民间一样,真正的强者从来都会大隐于市,不抱怨环境,逆境生长,谦虚低调,更加善于从文学、艺术、歌舞等身边事物汲取精神养料,陶冶情操,追求乐观豁达、自然洒脱的心境,敢于接受自我的渺小和平凡。天地之大,万类霜天竞自由,适者生存,物竞天择,无外乎天外有天、山外有山、人外有人,愿自己能够不忘初心,坚定脚步,砥砺前行,始终坚信美好新鲜的事物即将发生,永远感恩父母、热爱生活、热爱人民、热爱世界。

猜你喜欢

转载自blog.csdn.net/jing_zhong/article/details/127761120
今日推荐